lib.rs 24.1 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

#![cfg_attr(not(feature = "std"), no_std)]
20
21
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit="256"]
Gav Wood's avatar
Gav Wood committed
22

23
24
mod attestations;
mod claims;
25
mod parachains;
Gavin Wood's avatar
Gavin Wood committed
26
27
mod slot_range;
mod slots;
28
mod crowdfund;
Gav Wood's avatar
Gav Wood committed
29

30
use rstd::prelude::*;
31
use codec::{Encode, Decode};
32
use substrate_primitives::u32_trait::{_1, _2, _3, _4};
33
use primitives::{
34
	AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
Gavin Wood's avatar
Gavin Wood committed
35
	parachain, ValidityError,
36
};
37
use client::{
38
	block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult},
39
	runtime_api as client_api, impl_runtime_apis,
40
};
Gav Wood's avatar
Gav Wood committed
41
use sr_primitives::{
thiolliere's avatar
thiolliere committed
42
	ApplyResult, generic, Permill, Perbill, impl_opaque_keys, create_runtime_str, key_types,
Gavin Wood's avatar
Gavin Wood committed
43
	transaction_validity::{TransactionValidity, InvalidTransaction, TransactionValidityError},
44
45
	weights::{Weight, DispatchInfo}, curve::PiecewiseLinear,
	traits::{BlakeTwo256, Block as BlockT, StaticLookup, SignedExtension},
Gav Wood's avatar
Gav Wood committed
46
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
47
use version::RuntimeVersion;
48
use grandpa::{AuthorityId as GrandpaId, fg_primitives};
49
use babe_primitives::AuthorityId as BabeId;
50
use elections::VoteIndex;
51
52
53
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
use substrate_primitives::OpaqueMetadata;
54
use sr_staking_primitives::SessionIndex;
Gavin Wood's avatar
Gavin Wood committed
55
use srml_support::{
56
	parameter_types, construct_runtime, traits::{SplitTwoWays, Currency}
Gavin Wood's avatar
Gavin Wood committed
57
};
58
59
use authority_discovery_primitives::{AuthorityId as EncodedAuthorityId, Signature as EncodedSignature};
use im_online::sr25519::{AuthorityId as ImOnlineId, AuthoritySignature as ImOnlineSignature};
Gavin Wood's avatar
Gavin Wood committed
60
use system::offchain::TransactionSubmitter;
61

Gav Wood's avatar
Gav Wood committed
62
63
#[cfg(feature = "std")]
pub use staking::StakerStatus;
64
65
#[cfg(any(feature = "std", test))]
pub use sr_primitives::BuildStorage;
66
pub use timestamp::Call as TimestampCall;
67
pub use balances::Call as BalancesCall;
68
69
pub use attestations::{Call as AttestationsCall, MORE_ATTESTATIONS_IDENTIFIER};
pub use parachains::{Call as ParachainsCall, NEW_HEADS_IDENTIFIER};
70

71
72
73
74
75
76
77
78
/// Implementations of some helper traits passed into runtime modules as associated types.
pub mod impls;
use impls::{CurrencyToVoteHandler, WeightMultiplierUpdateHandler, ToAuthor, WeightToFee};

/// Constant values used within the runtime.
pub mod constants;
use constants::{time::*, currency::*};

79
80
81
82
// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

83
84
85
/*
// KUSAMA: Polkadot version identifier; may be uncommented for Polkadot mainnet.
/// Runtime version (Polkadot).
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
86
pub const VERSION: RuntimeVersion = RuntimeVersion {
87
88
	spec_name: create_runtime_str!("polkadot"),
	impl_name: create_runtime_str!("parity-polkadot"),
Gav Wood's avatar
Gav Wood committed
89
	authoring_version: 1,
André Silva's avatar
André Silva committed
90
	spec_version: 1000,
91
	impl_version: 0,
92
	apis: RUNTIME_API_VERSIONS,
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
93
};
94
95
96
97
98
99
100
101
*/

// KUSAMA: Kusama version identifier; may be removed for Polkadot mainnet.
/// Runtime version (Kusama).
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("kusama"),
	impl_name: create_runtime_str!("parity-kusama"),
	authoring_version: 1,
Gavin Wood's avatar
Gavin Wood committed
102
	spec_version: 1003,
103
104
105
	impl_version: 0,
	apis: RUNTIME_API_VERSIONS,
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
106

107
108
109
110
111
112
113
114
115
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

116
117
118
119
120
121
122
123
124
125
126
127
/// Avoid processing transactions that are anything except staking and claims.
///
/// RELEASE: This is only relevant for the initial PoA run-in period and may be removed
/// from the release runtime.
#[derive(Default, Encode, Decode, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct OnlyStakingAndClaims;
impl SignedExtension for OnlyStakingAndClaims {
	type AccountId = AccountId;
	type Call = Call;
	type AdditionalSigned = ();
	type Pre = ();
Gavin Wood's avatar
Gavin Wood committed
128
	fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) }
129
	fn validate(&self, _: &Self::AccountId, call: &Self::Call, _: DispatchInfo, _: usize)
Gavin Wood's avatar
Gavin Wood committed
130
		-> TransactionValidity
131
132
	{
		match call {
133
134
			Call::Staking(_) | Call::Claims(_) | Call::Sudo(_) | Call::Session(_) =>
				Ok(Default::default()),
Gavin Wood's avatar
Gavin Wood committed
135
			_ => Err(InvalidTransaction::Custom(ValidityError::NoPermission.into()).into()),
136
137
138
139
		}
	}
}

140
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
Gavin Wood's avatar
Gavin Wood committed
141

142
parameter_types! {
143
	pub const BlockHashCount: BlockNumber = 250;
144
145
146
	pub const MaximumBlockWeight: Weight = 1_000_000_000;
	pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
	pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
147
	pub const Version: RuntimeVersion = VERSION;
148
149
}

150
151
impl system::Trait for Runtime {
	type Origin = Origin;
152
	type Call = Call;
Gav Wood's avatar
Gav Wood committed
153
	type Index = Nonce;
154
155
156
157
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
Gav Wood's avatar
Gav Wood committed
158
	type Lookup = Indices;
159
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
160
	type WeightMultiplierUpdate = WeightMultiplierUpdateHandler;
Gav's avatar
Gav committed
161
	type Event = Event;
162
	type BlockHashCount = BlockHashCount;
163
164
165
	type MaximumBlockWeight = MaximumBlockWeight;
	type MaximumBlockLength = MaximumBlockLength;
	type AvailableBlockRatio = AvailableBlockRatio;
166
	type Version = Version;
167
168
}

169
parameter_types! {
170
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
171
172
173
174
175
176
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
}

impl babe::Trait for Runtime {
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
177
178
}

Gav Wood's avatar
Gav Wood committed
179
180
181
182
183
184
185
impl indices::Trait for Runtime {
	type IsDeadAccount = Balances;
	type AccountIndex = AccountIndex;
	type ResolveHint = indices::SimpleResolveHint<Self::AccountId, Self::AccountIndex>;
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
186
parameter_types! {
187
	pub const ExistentialDeposit: Balance = 10 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
188
189
190
191
192
193
194
195
196
197
	pub const TransferFee: Balance = 1 * CENTS;
	pub const CreationFee: Balance = 1 * CENTS;
	pub const TransactionBaseFee: Balance = 1 * CENTS;
	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
}

/// Splits fees 80/20 between treasury and block author.
pub type DealWithFees = SplitTwoWays<
	Balance,
	NegativeImbalance,
198
199
	_4, Treasury,   // 4 parts (80%) goes to the treasury.
	_1, ToAuthor,   // 1 part (20%) goes to the block author.
Gavin Wood's avatar
Gavin Wood committed
200
201
>;

202
impl balances::Trait for Runtime {
Gav's avatar
Gav committed
203
204
	type Balance = Balance;
	type OnFreeBalanceZero = Staking;
Gav Wood's avatar
Gav Wood committed
205
	type OnNewAccount = Indices;
Gav's avatar
Gav committed
206
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
207
	type TransactionPayment = DealWithFees;
208
209
	type DustRemoval = ();
	type TransferPayment = ();
Gavin Wood's avatar
Gavin Wood committed
210
211
212
213
214
	type ExistentialDeposit = ExistentialDeposit;
	type TransferFee = TransferFee;
	type CreationFee = CreationFee;
	type TransactionBaseFee = TransactionBaseFee;
	type TransactionByteFee = TransactionByteFee;
215
	type WeightToFee = WeightToFee;
Gav's avatar
Gav committed
216
217
}

218
parameter_types! {
219
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
220
221
}

222
impl timestamp::Trait for Runtime {
223
	type Moment = u64;
224
	type OnTimestampSet = Babe;
225
	type MinimumPeriod = MinimumPeriod;
226
227
}

Gavin Wood's avatar
Gavin Wood committed
228
parameter_types! {
229
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
230
231
232
233
}

// TODO: substrate#2986 implement this properly
impl authorship::Trait for Runtime {
234
	type FindAuthor = session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
235
236
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
237
	type EventHandler = Staking;
Gavin Wood's avatar
Gavin Wood committed
238
239
}

240
241
242
243
244
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

245
type SessionHandlers = (Grandpa, Babe, ImOnline, AuthorityDiscovery, Parachains);
246
impl_opaque_keys! {
247
	pub struct SessionKeys {
248
249
250
251
252
253
254
255
		#[id(key_types::GRANDPA)]
		pub grandpa: GrandpaId,
		#[id(key_types::BABE)]
		pub babe: BabeId,
		#[id(key_types::IM_ONLINE)]
		pub im_online: ImOnlineId,
		#[id(parachain::PARACHAIN_KEY_TYPE_ID)]
		pub parachain_validator: parachain::ValidatorId,
256
	}
257
258
259
260
261
262
263
264
}

// NOTE: `SessionHandler` and `SessionKeys` are co-dependent: One key will be used for each handler.
// The number and order of items in `SessionHandler` *MUST* be the same number and order of keys in
// `SessionKeys`.
// TODO: Introduce some structure to tie these together to make it a bit less of a footgun. This
// should be easy, since OneSessionHandler trait provides the `Key` as an associated type. #2858

thiolliere's avatar
thiolliere committed
265
266
267
268
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

269
impl session::Trait for Runtime {
270
271
	type OnSessionEnding = Staking;
	type SessionHandler = SessionHandlers;
272
	type ShouldEndSession = Babe;
Gav's avatar
Gav committed
273
	type Event = Event;
274
	type Keys = SessionKeys;
275
276
277
	type SelectInitialValidators = Staking;
	type ValidatorId = AccountId;
	type ValidatorIdOf = staking::StashOf<Self>;
thiolliere's avatar
thiolliere committed
278
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
279
280
281
282
283
}

impl session::historical::Trait for Runtime {
	type FullIdentification = staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = staking::ExposureOf<Self>;
284
285
}

thiolliere's avatar
thiolliere committed
286
287
288
289
290
291
292
293
294
295
296
srml_staking_reward_curve::build! {
	const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
		min_inflation: 0_025_000,
		max_inflation: 0_100_000,
		ideal_stake: 0_500_000,
		falloff: 0_050_000,
		max_piece_count: 40,
		test_precision: 0_005_000,
	);
}

297
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
298
	// Six sessions in an era (24 hours).
299
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
300
301
	// 28 eras for unbonding (28 days).
	pub const BondingDuration: staking::EraIndex = 28;
thiolliere's avatar
thiolliere committed
302
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
303
}
304

305
306
impl staking::Trait for Runtime {
	type OnRewardMinted = Treasury;
307
	type CurrencyToVote = CurrencyToVoteHandler;
Gav's avatar
Gav committed
308
	type Event = Event;
309
	type Currency = Balances;
310
	type Slash = Treasury;
311
	type Reward = ();
312
313
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
314
	type SessionInterface = Self;
315
	type Time = Timestamp;
thiolliere's avatar
thiolliere committed
316
	type RewardCurve = RewardCurve;
317
318
}

319
320
321
parameter_types! {
	pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
	pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
322
	pub const EmergencyVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES;
323
	pub const MinimumDeposit: Balance = 100 * DOLLARS;
324
	pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
325
	pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
326
327
}

328
329
330
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
331
	type Currency = Balances;
332
333
334
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
335
	type EmergencyVotingPeriod = EmergencyVotingPeriod;
336
	type MinimumDeposit = MinimumDeposit;
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
	/// A straight majority of the council can decide what their next motion is.
	type ExternalOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
	/// A super-majority can have the next scheduled referendum be a straight majority-carries vote.
	type ExternalMajorityOrigin = collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
	/// A unanimous council can have the next scheduled referendum be a straight default-carries
	/// (NTB) vote.
	type ExternalDefaultOrigin = collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>;
	/// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote
	/// be tabled immediately and with a shorter voting/enactment period.
	type FastTrackOrigin = collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>;
	// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
	type CancellationOrigin = collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>;
	// Any single technical committee member may veto a coming council proposal, however they can
	// only do it once and it lasts only for the cooloff period.
	type VetoOrigin = collective::EnsureMember<AccountId, TechnicalCollective>;
352
	type CooloffPeriod = CooloffPeriod;
353
}
354

355
356
type CouncilCollective = collective::Instance1;
impl collective::Trait<CouncilCollective> for Runtime {
357
358
359
360
361
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
362
parameter_types! {
363
364
365
	pub const CandidacyBond: Balance = 10 * DOLLARS;
	pub const VotingBond: Balance = 1 * DOLLARS;
	pub const VotingFee: Balance = 2 * DOLLARS;
thiolliere's avatar
thiolliere committed
366
	pub const MinimumVotingLock: Balance = 1 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
367
368
369
	pub const PresentSlashPerVoter: Balance = 1 * CENTS;
	pub const CarryCount: u32 = 6;
	// one additional vote should go by before an inactive voter can be reaped.
370
371
	pub const InactiveGracePeriod: VoteIndex = 1;
	pub const ElectionsVotingPeriod: BlockNumber = 2 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
372
373
374
	pub const DecayRatio: u32 = 0;
}

375
impl elections::Trait for Runtime {
376
	type Event = Event;
377
	type Currency = Balances;
378
379
	type BadPresentation = ();
	type BadReaper = ();
380
381
	type BadVoterIndex = ();
	type LoserCandidate = ();
382
	type ChangeMembers = Council;
Gavin Wood's avatar
Gavin Wood committed
383
384
385
	type CandidacyBond = CandidacyBond;
	type VotingBond = VotingBond;
	type VotingFee = VotingFee;
thiolliere's avatar
thiolliere committed
386
	type MinimumVotingLock = MinimumVotingLock;
Gavin Wood's avatar
Gavin Wood committed
387
388
389
	type PresentSlashPerVoter = PresentSlashPerVoter;
	type CarryCount = CarryCount;
	type InactiveGracePeriod = InactiveGracePeriod;
390
	type VotingPeriod = ElectionsVotingPeriod;
Gavin Wood's avatar
Gavin Wood committed
391
	type DecayRatio = DecayRatio;
392
393
}

394
395
type TechnicalCollective = collective::Instance2;
impl collective::Trait<TechnicalCollective> for Runtime {
396
397
398
399
400
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
}

401
402
403
404
405
406
407
408
409
410
impl membership::Trait<membership::Instance1> for Runtime {
	type Event = Event;
	type AddOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
	type RemoveOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
	type SwapOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
	type ResetOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
}

Gavin Wood's avatar
Gavin Wood committed
411
412
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
Gavin Wood's avatar
Gavin Wood committed
413
414
415
	pub const ProposalBondMinimum: Balance = 100 * DOLLARS;
	pub const SpendPeriod: BlockNumber = 24 * DAYS;
	pub const Burn: Permill = Permill::from_percent(5);
Gavin Wood's avatar
Gavin Wood committed
416
417
}

418
impl treasury::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
419
	type Currency = Balances;
420
421
	type ApproveOrigin = collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>;
	type RejectOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
422
	type Event = Event;
423
424
	type MintedForSpending = ();
	type ProposalRejection = ();
Gavin Wood's avatar
Gavin Wood committed
425
426
427
428
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
429
}
430

431
432
433
434
435
436
impl offences::Trait for Runtime {
	type Event = Event;
	type IdentificationTuple = session::historical::IdentificationTuple<Self>;
	type OnOffenceHandler = Staking;
}

Gavin Wood's avatar
Gavin Wood committed
437
438
type SubmitTransaction = TransactionSubmitter<ImOnlineId, Runtime, UncheckedExtrinsic>;

439
impl im_online::Trait for Runtime {
thiolliere's avatar
thiolliere committed
440
	type AuthorityId = ImOnlineId;
441
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
442
443
	type Call = Call;
	type SubmitTransaction = SubmitTransaction;
444
	type ReportUnresponsiveness = ();
445
446
}

447
448
impl authority_discovery::Trait for Runtime {}

449
450
451
452
impl grandpa::Trait for Runtime {
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
453
454
455
456
457
458
parameter_types! {
	pub const WindowSize: BlockNumber = finality_tracker::DEFAULT_WINDOW_SIZE.into();
	pub const ReportLatency: BlockNumber = finality_tracker::DEFAULT_REPORT_LATENCY.into();
}

impl finality_tracker::Trait for Runtime {
459
	type OnFinalizationStalled = ();
Gavin Wood's avatar
Gavin Wood committed
460
461
462
463
	type WindowSize = WindowSize;
	type ReportLatency = ReportLatency;
}

464
465
466
467
parameter_types! {
	pub const AttestationPeriod: BlockNumber = 50;
}

468
469
470
impl attestations::Trait for Runtime {
	type AttestationPeriod = AttestationPeriod;
	type ValidatorIdentities = parachains::ValidatorIdentities<Runtime>;
471
	type RewardAttestation = Staking;
472
473
}

474
475
476
impl parachains::Trait for Runtime {
	type Origin = Origin;
	type Call = Call;
477
	type ParachainCurrency = Balances;
478
}
479

Gavin Wood's avatar
Gavin Wood committed
480
parameter_types!{
481
	pub const LeasePeriod: BlockNumber = 100_000;
Gavin Wood's avatar
Gavin Wood committed
482
483
484
485
486
487
488
489
490
491
492
	pub const EndingPeriod: BlockNumber = 1000;
}

impl slots::Trait for Runtime {
	type Event = Event;
	type Currency = balances::Module<Self>;
	type Parachains = parachains::Module<Self>;
	type LeasePeriod = LeasePeriod;
	type EndingPeriod = EndingPeriod;
}

493
parameter_types!{
494
	// KUSAMA: for mainnet this should be removed.
495
	pub const Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:";
496
497
	// KUSAMA: for mainnet this should be uncommented.
	//pub const Prefix: &'static [u8] = b"Pay DOTs to the Polkadot account:";
498
499
500
501
502
503
504
505
}

impl claims::Trait for Runtime {
	type Event = Event;
	type Currency = Balances;
	type Prefix = Prefix;
}

Gav Wood's avatar
Gav Wood committed
506
507
508
509
510
impl sudo::Trait for Runtime {
	type Event = Event;
	type Proposal = Call;
}

511
construct_runtime!(
512
	pub enum Runtime where
513
		Block = Block,
514
		NodeBlock = primitives::Block,
515
		UncheckedExtrinsic = UncheckedExtrinsic
516
	{
517
		// Basic stuff; balances is uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
518
		System: system::{Module, Call, Storage, Config, Event},
519
520

		// Must be before session.
521
		Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
522
523

		Timestamp: timestamp::{Module, Call, Storage, Inherent},
Gav Wood's avatar
Gav Wood committed
524
		Indices: indices,
525
526
527
528
		Balances: balances::{Module, Call, Storage, Config<T>, Event<T>},

		// Consensus support.
		Authorship: authorship::{Module, Call, Storage},
Gavin Wood's avatar
Gavin Wood committed
529
		Staking: staking::{default, OfflineWorker},
530
		Offences: offences::{Module, Call, Storage, Event},
531
		Session: session::{Module, Call, Storage, Event, Config<T>},
532
533
		FinalityTracker: finality_tracker::{Module, Call, Inherent},
		Grandpa: grandpa::{Module, Call, Storage, Config, Event},
thiolliere's avatar
thiolliere committed
534
		ImOnline: im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
535
		AuthorityDiscovery: authority_discovery::{Module, Call, Config<T>},
536
537

		// Governance stuff; uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
538
		Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
539
540
541
		Council: collective::<Instance1>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
		TechnicalCommittee: collective::<Instance2>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
		Elections: elections::{Module, Call, Storage, Event<T>, Config<T>},
542
		TechnicalMembership: membership::<Instance1>::{Module, Call, Storage, Event<T>, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
543
		Treasury: treasury::{Module, Call, Storage, Event<T>},
544
545
546
547
548
549

		// Claims. Usable initially.
		Claims: claims::{Module, Call, Storage, Event<T>, Config<T>, ValidateUnsigned},

		// Parachains stuff; slots are disabled (no auctions initially). The rest are safe as they
		// have no public dispatchables.
550
		Parachains: parachains::{Module, Call, Storage, Config<T>, Inherent, Origin},
551
		Attestations: attestations::{Module, Call, Storage},
Gavin Wood's avatar
Gavin Wood committed
552
		Slots: slots::{Module, Call, Storage, Event<T>},
553
554
555
556

		// Sudo. Usable initially.
		// RELEASE: remove this for release build.
		Sudo: sudo,
Gav's avatar
Gav committed
557
	}
558
559
560
);

/// The address format for describing accounts.
Gav Wood's avatar
Gav Wood committed
561
pub type Address = <Indices as StaticLookup>::Source;
562
/// Block header type as expected by this runtime.
563
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
564
565
566
567
568
569
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// A Block signed with a Justification
pub type SignedBlock = generic::SignedBlock<Block>;
/// BlockId type as expected by this runtime.
pub type BlockId = generic::BlockId<Block>;
570
571
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
572
573
	// RELEASE: remove this for release build.
	OnlyStakingAndClaims,
574
	system::CheckVersion<Runtime>,
575
	system::CheckGenesis<Runtime>,
576
577
578
	system::CheckEra<Runtime>,
	system::CheckNonce<Runtime>,
	system::CheckWeight<Runtime>,
579
	balances::TakeFees<Runtime>,
580
);
581
/// Unchecked extrinsic type as expected by this runtime.
582
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
583
/// Extrinsic type that has already been checked.
Gav Wood's avatar
Gav Wood committed
584
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
585
/// Executive: handles dispatch to the various modules.
586
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
587
588

impl_runtime_apis! {
589
	impl client_api::Core<Block> for Runtime {
590
591
592
593
594
595
596
		fn version() -> RuntimeVersion {
			VERSION
		}

		fn execute_block(block: Block) {
			Executive::execute_block(block)
		}
597

598
599
		fn initialize_block(header: &<Block as BlockT>::Header) {
			Executive::initialize_block(header)
600
601
		}
	}
Gav's avatar
Gav committed
602

603
	impl client_api::Metadata<Block> for Runtime {
604
605
606
		fn metadata() -> OpaqueMetadata {
			Runtime::metadata().into()
		}
Gav's avatar
Gav committed
607
608
	}

609
	impl block_builder_api::BlockBuilder<Block> for Runtime {
610
611
612
613
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
			Executive::apply_extrinsic(extrinsic)
		}

614
615
		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
616
		}
617

618
619
		fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
			data.create_extrinsics()
620
		}
621

622
623
		fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
			data.check_extrinsics(&block)
624
		}
625

626
627
628
		fn random_seed() -> <Block as BlockT>::Hash {
			System::random_seed()
		}
629
630
	}

631
	impl client_api::TaggedTransactionQueue<Block> for Runtime {
632
633
634
		fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
			Executive::validate_transaction(tx)
		}
Gav's avatar
Gav committed
635
	}
636

637
638
639
640
641
642
	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
		fn offchain_worker(number: sr_primitives::traits::NumberFor<Block>) {
			Executive::offchain_worker(number)
		}
	}

643
	impl parachain::ParachainHost<Block> for Runtime {
Gav Wood's avatar
Gav Wood committed
644
		fn validators() -> Vec<parachain::ValidatorId> {
645
			Parachains::authorities()
646
647
		}
		fn duty_roster() -> parachain::DutyRoster {
648
			Parachains::calculate_duty_roster().0
649
650
651
652
		}
		fn active_parachains() -> Vec<parachain::Id> {
			Parachains::active_parachains()
		}
653
654
		fn parachain_status(id: parachain::Id) -> Option<parachain::Status> {
			Parachains::parachain_status(&id)
655
656
657
658
		}
		fn parachain_code(id: parachain::Id) -> Option<Vec<u8>> {
			Parachains::parachain_code(&id)
		}
659
660
661
662
		fn ingress(to: parachain::Id, since: Option<BlockNumber>)
			-> Option<parachain::StructuredUnroutedIngress>
		{
			Parachains::ingress(to, since).map(parachain::StructuredUnroutedIngress)
663
		}
664
	}
665
666

	impl fg_primitives::GrandpaApi<Block> for Runtime {
667
		fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
668
669
670
671
			Grandpa::grandpa_authorities()
		}
	}

672
	impl babe_primitives::BabeApi<Block> for Runtime {
673
		fn configuration() -> babe_primitives::BabeConfiguration {
674
675
676
677
678
679
680
			// The choice of `c` parameter (where `1 - c` represents the
			// probability of a slot being empty), is done in accordance to the
			// slot duration and expected target block time, for safely
			// resisting network delays of maximum two seconds.
			// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
			babe_primitives::BabeConfiguration {
				slot_duration: Babe::slot_duration(),
681
				epoch_length: EpochDuration::get(),
682
				c: PRIMARY_PROBABILITY,
683
				genesis_authorities: Babe::authorities(),
684
				randomness: Babe::randomness(),
685
				secondary_slots: true,
686
			}
687
688
689
		}
	}

690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
	impl authority_discovery_primitives::AuthorityDiscoveryApi<Block> for Runtime {
		fn authorities() -> Vec<EncodedAuthorityId> {
			AuthorityDiscovery::authorities().into_iter()
				.map(|id| id.encode())
				.map(EncodedAuthorityId)
				.collect()
		}

		fn sign(payload: &Vec<u8>) -> Option<(EncodedSignature, EncodedAuthorityId)> {
			AuthorityDiscovery::sign(payload).map(|(sig, id)| {
				(EncodedSignature(sig.encode()), EncodedAuthorityId(id.encode()))
			})
		}

		fn verify(payload: &Vec<u8>, signature: &EncodedSignature, authority_id: &EncodedAuthorityId) -> bool {
			let signature = match ImOnlineSignature::decode(&mut &signature.0[..]) {
				Ok(s) => s,
				_ => return false,
			};

			let authority_id = match ImOnlineId::decode(&mut &authority_id.0[..]) {
				Ok(id) => id,
				_ => return false,
			};

			AuthorityDiscovery::verify(payload, signature, authority_id)
		}
	}

719
720
721
722
723
724
	impl substrate_session::SessionKeys<Block> for Runtime {
		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
			let seed = seed.as_ref().map(|s| rstd::str::from_utf8(&s).expect("Seed is an utf8 string"));
			SessionKeys::generate(seed)
		}
	}
Gav's avatar
Gav committed
725
}