lib.rs 31.4 KB
Newer Older
Shawn Tabrizi's avatar
Shawn Tabrizi committed
1
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
Gav's avatar
Gav committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 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
use sp_std::prelude::*;
24
use sp_core::u32_trait::{_1, _2, _3, _4, _5};
25
use codec::{Encode, Decode};
26
use primitives::{
27
	AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
28
	parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext}, ValidityError,
29
};
30
use runtime_common::{attestations, claims, parachains, registrar, slots,
31
	impls::{CurrencyToVoteHandler, TargetedFeeAdjustment, ToAuthor},
32
33
34
	NegativeImbalance, BlockHashCount, MaximumBlockWeight, AvailableBlockRatio,
	MaximumBlockLength,
};
35
use sp_runtime::{
Gavin Wood's avatar
Gavin Wood committed
36
	create_runtime_str, generic, impl_opaque_keys,
37
	ApplyExtrinsicResult, KeyTypeId, Percent, Permill, Perbill, RuntimeDebug,
38
	transaction_validity::{
39
		TransactionValidity, InvalidTransaction, TransactionValidityError, TransactionSource, TransactionPriority,
40
	},
41
	curve::PiecewiseLinear,
42
43
44
45
	traits::{
		BlakeTwo256, Block as BlockT, SignedExtension, OpaqueKeys, ConvertInto, IdentityLookup,
		DispatchInfoOf,
	},
Gav Wood's avatar
Gav Wood committed
46
};
47
48
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
49
use version::RuntimeVersion;
50
use grandpa::{AuthorityId as GrandpaId, fg_primitives};
51
52
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
53
54
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
55
use frame_support::{
56
	parameter_types, construct_runtime, traits::{KeyOwnerProofSystem, SplitTwoWays, Randomness},
Gavin Wood's avatar
Gavin Wood committed
57
};
thiolliere's avatar
thiolliere committed
58
use im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
59
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
Gavin Wood's avatar
Gavin Wood committed
60
use system::offchain::TransactionSubmitter;
Gavin Wood's avatar
Gavin Wood committed
61
use transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
62
use session::{historical as session_historical};
63

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

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

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

81
82
83
84
/// Runtime version (Kusama).
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("kusama"),
	impl_name: create_runtime_str!("parity-kusama"),
85
	authoring_version: 2,
86
	spec_version: 1057,
André Silva's avatar
André Silva committed
87
	impl_version: 1,
88
89
	apis: RUNTIME_API_VERSIONS,
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
90

91
92
93
94
95
96
97
98
99
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

100
/// Avoid processing transactions from slots and parachain registrar.
101
#[derive(Default, Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug)]
102
103
pub struct RestrictFunctionality;
impl SignedExtension for RestrictFunctionality {
Gavin Wood's avatar
Gavin Wood committed
104
	const IDENTIFIER: &'static str = "RestrictFunctionality";
105
106
107
108
	type AccountId = AccountId;
	type Call = Call;
	type AdditionalSigned = ();
	type Pre = ();
109

110
	fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
111

112
113
114
115
116
117
118
	fn validate(
		&self,
		_: &Self::AccountId,
		call: &Self::Call,
		_: &DispatchInfoOf<Self::Call>,
		_: usize
	)
Gavin Wood's avatar
Gavin Wood committed
119
		-> TransactionValidity
120
121
	{
		match call {
Gavin Wood's avatar
Gavin Wood committed
122
			Call::Slots(_) | Call::Registrar(_)
123
124
				=> Err(InvalidTransaction::Custom(ValidityError::NoPermission.into()).into()),
			_ => Ok(Default::default()),
125
126
127
128
		}
	}
}

129
parameter_types! {
130
	pub const Version: RuntimeVersion = VERSION;
131
132
}

133
134
impl system::Trait for Runtime {
	type Origin = Origin;
135
	type Call = Call;
Gav Wood's avatar
Gav Wood committed
136
	type Index = Nonce;
137
138
139
140
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
141
	type Lookup = IdentityLookup<Self::AccountId>;
142
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
Gav's avatar
Gav committed
143
	type Event = Event;
144
	type BlockHashCount = BlockHashCount;
145
146
147
	type MaximumBlockWeight = MaximumBlockWeight;
	type MaximumBlockLength = MaximumBlockLength;
	type AvailableBlockRatio = AvailableBlockRatio;
148
	type Version = Version;
149
	type ModuleToIndex = ModuleToIndex;
150
151
	type AccountData = balances::AccountData<Balance>;
	type OnNewAccount = ();
152
	type OnKilledAccount = ();
153
154
}

Gavin Wood's avatar
Gavin Wood committed
155
156
157
158
159
160
161
impl scheduler::Trait for Runtime {
	type Event = Event;
	type Origin = Origin;
	type Call = Call;
	type MaximumWeight = MaximumBlockWeight;
}

162
parameter_types! {
163
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
164
165
166
167
168
169
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
}

impl babe::Trait for Runtime {
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
170
171
172

	// session module is the trigger
	type EpochChangeTrigger = babe::ExternalTrigger;
173
174
}

Gavin Wood's avatar
Gavin Wood committed
175
176
177
178
parameter_types! {
	pub const IndexDeposit: Balance = 1 * DOLLARS;
}

Gav Wood's avatar
Gav Wood committed
179
180
impl indices::Trait for Runtime {
	type AccountIndex = AccountIndex;
181
182
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
183
184
185
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
186
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
187
	pub const ExistentialDeposit: Balance = 1 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
188
189
190
191
192
}

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

198
impl balances::Trait for Runtime {
Gav's avatar
Gav committed
199
	type Balance = Balance;
200
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
201
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
202
	type ExistentialDeposit = ExistentialDeposit;
203
	type AccountStore = System;
204
205
206
207
208
}

parameter_types! {
	pub const TransactionBaseFee: Balance = 1 * CENTS;
	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
209
210
	// for a sane configuration, this should always be less than `AvailableBlockRatio`.
	pub const TargetBlockFullness: Perbill = Perbill::from_percent(25);
211
212
213
214
215
}

impl transaction_payment::Trait for Runtime {
	type Currency = Balances;
	type OnTransactionPayment = DealWithFees;
Gavin Wood's avatar
Gavin Wood committed
216
217
	type TransactionBaseFee = TransactionBaseFee;
	type TransactionByteFee = TransactionByteFee;
218
	type WeightToFee = WeightToFee;
219
	type FeeMultiplierUpdate = TargetedFeeAdjustment<TargetBlockFullness, Self>;
Gav's avatar
Gav committed
220
221
}

222
parameter_types! {
223
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
224
}
225
impl timestamp::Trait for Runtime {
226
	type Moment = u64;
227
	type OnTimestampSet = Babe;
228
	type MinimumPeriod = MinimumPeriod;
229
230
}

Gavin Wood's avatar
Gavin Wood committed
231
parameter_types! {
232
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
233
234
235
236
}

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

243
244
245
246
247
248
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

impl_opaque_keys! {
249
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
250
251
252
253
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
		pub parachain_validator: Parachains,
Gavin Wood's avatar
Gavin Wood committed
254
		pub authority_discovery: AuthorityDiscovery,
255
	}
256
257
}

thiolliere's avatar
thiolliere committed
258
259
260
261
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

262
impl session::Trait for Runtime {
Gav's avatar
Gav committed
263
	type Event = Event;
264
265
	type ValidatorId = AccountId;
	type ValidatorIdOf = staking::StashOf<Self>;
Gavin Wood's avatar
Gavin Wood committed
266
	type ShouldEndSession = Babe;
267
	type NextSessionRotation = Babe;
Gavin Wood's avatar
Gavin Wood committed
268
269
270
	type SessionManager = Staking;
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
thiolliere's avatar
thiolliere committed
271
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
272
273
274
275
}

impl session::historical::Trait for Runtime {
	type FullIdentification = staking::Exposure<AccountId, Balance>;
276
	type FullIdentificationOf = staking::ExposureOf<Runtime>;
277
278
}

279
pallet_staking_reward_curve::build! {
thiolliere's avatar
thiolliere committed
280
281
282
283
284
285
286
287
288
289
	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,
	);
}

290
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
291
	// Six sessions in an era (6 hours).
292
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
293
	// 28 eras for unbonding (7 days).
Gavin Wood's avatar
Gavin Wood committed
294
	pub const BondingDuration: staking::EraIndex = 28;
Gavin Wood's avatar
Gavin Wood committed
295
	// 28 eras in which slashes can be cancelled (7 days).
Gavin Wood's avatar
Gavin Wood committed
296
	pub const SlashDeferDuration: staking::EraIndex = 28;
thiolliere's avatar
thiolliere committed
297
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
Gavin Wood's avatar
Gavin Wood committed
298
	pub const MaxNominatorRewardedPerValidator: u32 = 64;
299
300
	// quarter of the last session will be for election.
	pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4;
301
}
302

303
impl staking::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
304
	type Currency = Balances;
305
	type UnixTime = Timestamp;
306
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
307
	type RewardRemainder = Treasury;
Gav's avatar
Gav committed
308
	type Event = Event;
309
	type Slash = Treasury;
310
	type Reward = ();
311
312
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
313
	type SlashDeferDuration = SlashDeferDuration;
Gavin Wood's avatar
Gavin Wood committed
314
315
	// A majority of the council can cancel the slash.
	type SlashCancelOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
316
	type SessionInterface = Self;
thiolliere's avatar
thiolliere committed
317
	type RewardCurve = RewardCurve;
Gavin Wood's avatar
Gavin Wood committed
318
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
319
320
321
322
	type NextNewSession = Session;
	type ElectionLookahead = ElectionLookahead;
	type Call = Call;
	type SubmitTransaction = TransactionSubmitter<(), Runtime, UncheckedExtrinsic>;
323
	type UnsignedPriority = StakingUnsignedPriority;
324
325
}

326
parameter_types! {
327
328
	pub const LaunchPeriod: BlockNumber = 7 * DAYS;
	pub const VotingPeriod: BlockNumber = 7 * DAYS;
329
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
Gavin Wood's avatar
Gavin Wood committed
330
	pub const MinimumDeposit: Balance = 1 * DOLLARS;
331
332
	pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
333
	// One cent: $10,000 / MB
Gavin Wood's avatar
Gavin Wood committed
334
	pub const PreimageByteDeposit: Balance = 10 * MILLICENTS;
335
	pub const InstantAllowed: bool = true;
336
337
}

338
339
340
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
341
	type Currency = Balances;
342
343
344
345
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
	type MinimumDeposit = MinimumDeposit;
346
347
	/// A straight majority of the council can decide what their next motion is.
	type ExternalOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
348
	/// A majority can have the next scheduled referendum be a straight majority-carries vote.
349
	type ExternalMajorityOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
350
351
352
353
354
355
	/// 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>;
356
357
358
	type InstantOrigin = collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>;
	type InstantAllowed = InstantAllowed;
	type FastTrackVotingPeriod = FastTrackVotingPeriod;
359
360
361
362
363
	// 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>;
364
	type CooloffPeriod = CooloffPeriod;
Gavin Wood's avatar
Gavin Wood committed
365
366
	type PreimageByteDeposit = PreimageByteDeposit;
	type Slash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
367
	type Scheduler = Scheduler;
368
}
369

370
371
372
373
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
}

374
375
type CouncilCollective = collective::Instance1;
impl collective::Trait<CouncilCollective> for Runtime {
376
377
378
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
379
	type MotionDuration = CouncilMotionDuration;
380
381
}

Gavin Wood's avatar
Gavin Wood committed
382
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
383
384
	pub const CandidacyBond: Balance = 1 * DOLLARS;
	pub const VotingBond: Balance = 5 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
385
386
	/// Daily council elections.
	pub const TermDuration: BlockNumber = 24 * HOURS;
Kian Paimani's avatar
Kian Paimani committed
387
388
	pub const DesiredMembers: u32 = 13;
	pub const DesiredRunnersUp: u32 = 7;
389
390
391
}

impl elections_phragmen::Trait for Runtime {
392
	type Event = Event;
393
394
	type Currency = Balances;
	type ChangeMembers = Council;
395
	type InitializeMembers = Council;
396
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
397
398
	type CandidacyBond = CandidacyBond;
	type VotingBond = VotingBond;
399
400
401
	type LoserCandidate = Treasury;
	type BadReport = Treasury;
	type KickedMember = Treasury;
Gavin Wood's avatar
Gavin Wood committed
402
403
404
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
	type TermDuration = TermDuration;
405
406
}

407
408
409
410
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
}

411
412
type TechnicalCollective = collective::Instance2;
impl collective::Trait<TechnicalCollective> for Runtime {
413
414
415
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
416
	type MotionDuration = TechnicalMotionDuration;
417
418
}

419
420
421
422
423
424
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>;
425
	type PrimeOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
426
427
428
429
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
}

Gavin Wood's avatar
Gavin Wood committed
430
431
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
Gavin Wood's avatar
Gavin Wood committed
432
	pub const ProposalBondMinimum: Balance = 20 * DOLLARS;
433
	pub const SpendPeriod: BlockNumber = 6 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
434
	pub const Burn: Permill = Permill::from_percent(0);
Gavin Wood's avatar
Gavin Wood committed
435
436
437
438
439

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
	pub const TipReportDepositBase: Balance = 1 * DOLLARS;
	pub const TipReportDepositPerByte: Balance = 1 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
440
441
}

442
impl treasury::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
443
	type Currency = Balances;
444
	type ApproveOrigin = collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>;
445
	type RejectOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
Gavin Wood's avatar
Gavin Wood committed
446
447
448
449
450
	type Tippers = ElectionsPhragmen;
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
	type TipReportDepositPerByte = TipReportDepositPerByte;
451
	type Event = Event;
452
	type ProposalRejection = Treasury;
Gavin Wood's avatar
Gavin Wood committed
453
454
455
456
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
457
}
458

459
460
461
462
463
464
impl offences::Trait for Runtime {
	type Event = Event;
	type IdentificationTuple = session::historical::IdentificationTuple<Self>;
	type OnOffenceHandler = Staking;
}

Gavin Wood's avatar
Gavin Wood committed
465
466
impl authority_discovery::Trait for Runtime {}

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

469
470
471
472
parameter_types! {
	pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _;
}

473
474
475
476
477
parameter_types! {
	pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

478
impl im_online::Trait for Runtime {
thiolliere's avatar
thiolliere committed
479
	type AuthorityId = ImOnlineId;
480
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
481
482
	type Call = Call;
	type SubmitTransaction = SubmitTransaction;
483
	type ReportUnresponsiveness = Offences;
484
	type SessionDuration = SessionDuration;
485
	type UnsignedPriority = StakingUnsignedPriority;
486
487
}

488
489
490
491
impl grandpa::Trait for Runtime {
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
492
493
494
495
496
497
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 {
498
	type OnFinalizationStalled = ();
Gavin Wood's avatar
Gavin Wood committed
499
500
501
502
	type WindowSize = WindowSize;
	type ReportLatency = ReportLatency;
}

503
504
505
506
parameter_types! {
	pub const AttestationPeriod: BlockNumber = 50;
}

507
508
509
impl attestations::Trait for Runtime {
	type AttestationPeriod = AttestationPeriod;
	type ValidatorIdentities = parachains::ValidatorIdentities<Runtime>;
510
	type RewardAttestation = Staking;
511
512
}

513
514
515
parameter_types! {
	pub const MaxCodeSize: u32 = 10 * 1024 * 1024; // 10 MB
	pub const MaxHeadDataSize: u32 = 20 * 1024; // 20 KB
516
517
518
	pub const ValidationUpgradeFrequency: BlockNumber = 2 * DAYS;
	pub const ValidationUpgradeDelay: BlockNumber = 8 * HOURS;
	pub const SlashPeriod: BlockNumber = 7 * DAYS;
519
520
}

521
522
523
impl parachains::Trait for Runtime {
	type Origin = Origin;
	type Call = Call;
524
	type ParachainCurrency = Balances;
525
	type BlockNumberConversion = sp_runtime::traits::Identity;
526
	type Randomness = RandomnessCollectiveFlip;
527
528
	type ActiveParachains = Registrar;
	type Registrar = Registrar;
529
530
	type MaxCodeSize = MaxCodeSize;
	type MaxHeadDataSize = MaxHeadDataSize;
531
532
533
534
535

	type ValidationUpgradeFrequency = ValidationUpgradeFrequency;
	type ValidationUpgradeDelay = ValidationUpgradeDelay;
	type SlashPeriod = SlashPeriod;

536
537
538
539
	type Proof = session::historical::Proof;
	type KeyOwnerProofSystem = session::historical::Module<Self>;
	type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple;
	type ReportOffence = Offences;
540
	type BlockHashConversion = sp_runtime::traits::Identity;
541
542
543
}

parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
544
	pub const ParathreadDeposit: Balance = 5 * DOLLARS;
545
546
547
548
549
550
551
552
553
554
555
556
	pub const QueueSize: usize = 2;
	pub const MaxRetries: u32 = 3;
}

impl registrar::Trait for Runtime {
	type Event = Event;
	type Origin = Origin;
	type Currency = Balances;
	type ParathreadDeposit = ParathreadDeposit;
	type SwapAux = Slots;
	type QueueSize = QueueSize;
	type MaxRetries = MaxRetries;
557
}
558

Gavin Wood's avatar
Gavin Wood committed
559
parameter_types! {
560
	pub const LeasePeriod: BlockNumber = 100_000;
Gavin Wood's avatar
Gavin Wood committed
561
562
563
564
565
	pub const EndingPeriod: BlockNumber = 1000;
}

impl slots::Trait for Runtime {
	type Event = Event;
566
567
	type Currency = Balances;
	type Parachains = Registrar;
Gavin Wood's avatar
Gavin Wood committed
568
569
	type LeasePeriod = LeasePeriod;
	type EndingPeriod = EndingPeriod;
570
	type Randomness = RandomnessCollectiveFlip;
Gavin Wood's avatar
Gavin Wood committed
571
572
}

Gavin Wood's avatar
Gavin Wood committed
573
parameter_types! {
574
575
576
577
578
	pub const Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:";
}

impl claims::Trait for Runtime {
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
579
	type VestingSchedule = Vesting;
580
581
582
	type Prefix = Prefix;
}

583
parameter_types! {
584
	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
Gavin Wood's avatar
Gavin Wood committed
585
586
587
	pub const BasicDeposit: Balance = 10 * DOLLARS;       // 258 bytes on-chain
	pub const FieldDeposit: Balance = 250 * CENTS;        // 66 bytes on-chain
	pub const SubAccountDeposit: Balance = 2 * DOLLARS;   // 53 bytes on-chain
Gavin Wood's avatar
Gavin Wood committed
588
589
	pub const MaxSubAccounts: u32 = 100;
	pub const MaxAdditionalFields: u32 = 100;
590
591
592
593
594
595
596
597
598
}

impl identity::Trait for Runtime {
	type Event = Event;
	type Currency = Balances;
	type Slashed = Treasury;
	type BasicDeposit = BasicDeposit;
	type FieldDeposit = FieldDeposit;
	type SubAccountDeposit = SubAccountDeposit;
Gavin Wood's avatar
Gavin Wood committed
599
600
	type MaxSubAccounts = MaxSubAccounts;
	type MaxAdditionalFields = MaxAdditionalFields;
601
602
603
604
	type RegistrarOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
	type ForceOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
}

Gavin Wood's avatar
Gavin Wood committed
605
606
parameter_types! {
	// One storage item; value is size 4+4+16+32 bytes = 56 bytes.
Gavin Wood's avatar
Gavin Wood committed
607
	pub const MultisigDepositBase: Balance = 30 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
608
	// Additional storage item size of 32 bytes.
Gavin Wood's avatar
Gavin Wood committed
609
	pub const MultisigDepositFactor: Balance = 5 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
610
611
612
613
614
615
616
617
618
619
620
621
	pub const MaxSignatories: u16 = 100;
}

impl utility::Trait for Runtime {
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
	type MultisigDepositBase = MultisigDepositBase;
	type MultisigDepositFactor = MultisigDepositFactor;
	type MaxSignatories = MaxSignatories;
}

622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
parameter_types! {
	pub const ConfigDepositBase: Balance = 5 * DOLLARS;
	pub const FriendDepositFactor: Balance = 50 * CENTS;
	pub const MaxFriends: u16 = 9;
	pub const RecoveryDeposit: Balance = 5 * DOLLARS;
}

impl recovery::Trait for Runtime {
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
	type ConfigDepositBase = ConfigDepositBase;
	type FriendDepositFactor = FriendDepositFactor;
	type MaxFriends = MaxFriends;
	type RecoveryDeposit = RecoveryDeposit;
}

parameter_types! {
	pub const CandidateDeposit: Balance = 10 * DOLLARS;
	pub const WrongSideDeduction: Balance = 2 * DOLLARS;
	pub const MaxStrikes: u32 = 10;
	pub const RotationPeriod: BlockNumber = 80 * HOURS;
	pub const PeriodSpend: Balance = 500 * DOLLARS;
	pub const MaxLockDuration: BlockNumber = 36 * 30 * DAYS;
	pub const ChallengePeriod: BlockNumber = 7 * DAYS;
}

impl society::Trait for Runtime {
	type Event = Event;
	type Currency = Balances;
	type Randomness = RandomnessCollectiveFlip;
	type CandidateDeposit = CandidateDeposit;
	type WrongSideDeduction = WrongSideDeduction;
	type MaxStrikes = MaxStrikes;
	type PeriodSpend = PeriodSpend;
	type MembershipChanged = ();
	type RotationPeriod = RotationPeriod;
	type MaxLockDuration = MaxLockDuration;
	type FounderSetOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
	type SuspensionJudgementOrigin = society::EnsureFounder<Runtime>;
	type ChallengePeriod = ChallengePeriod;
}

665
666
667
668
parameter_types! {
	pub const MinVestedTransfer: Balance = 100 * DOLLARS;
}

Gavin Wood's avatar
Gavin Wood committed
669
670
671
672
impl vesting::Trait for Runtime {
	type Event = Event;
	type Currency = Balances;
	type BlockNumberToBalance = ConvertInto;
673
	type MinVestedTransfer = MinVestedTransfer;
Gavin Wood's avatar
Gavin Wood committed
674
675
}

Gavin Wood's avatar
Gavin Wood committed
676
construct_runtime! {
677
	pub enum Runtime where
678
		Block = Block,
679
		NodeBlock = primitives::Block,
680
		UncheckedExtrinsic = UncheckedExtrinsic
681
	{
682
		// Basic stuff; balances is uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
683
		System: system::{Module, Call, Storage, Config, Event<T>},
Ashley's avatar
Ashley committed
684
		RandomnessCollectiveFlip: randomness_collective_flip::{Module, Storage},
685
686

		// Must be before session.
687
		Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
688
689

		Timestamp: timestamp::{Module, Call, Storage, Inherent},
Gavin Wood's avatar
Gavin Wood committed
690
		Indices: indices::{Module, Call, Storage, Config<T>, Event<T>},
691
		Balances: balances::{Module, Call, Storage, Config<T>, Event<T>},
692
		TransactionPayment: transaction_payment::{Module, Storage},
693
694
695

		// Consensus support.
		Authorship: authorship::{Module, Call, Storage},
Kian Paimani's avatar
Kian Paimani committed
696
		Staking: staking::{Module, Call, Storage, Config<T>, Event<T>, ValidateUnsigned},
697
		Offences: offences::{Module, Call, Storage, Event},
698
		Historical: session_historical::{Module},
699
		Session: session::{Module, Call, Storage, Event, Config<T>},
700
		FinalityTracker: finality_tracker::{Module, Call, Storage, Inherent},
701
		Grandpa: grandpa::{Module, Call, Storage, Config, Event},
thiolliere's avatar
thiolliere committed
702
		ImOnline: im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
703
		AuthorityDiscovery: authority_discovery::{Module, Call, Config},
704
705

		// Governance stuff; uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
706
		Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
707
708
		Council: collective::<Instance1>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
		TechnicalCommittee: collective::<Instance2>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
709
		ElectionsPhragmen: elections_phragmen::{Module, Call, Storage, Event<T>, Config<T>},
710
		TechnicalMembership: membership::<Instance1>::{Module, Call, Storage, Event<T>, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
711
		Treasury: treasury::{Module, Call, Storage, Event<T>},
712
713
714
715
716
717

		// 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.
718
		Parachains: parachains::{Module, Call, Storage, Config, Inherent, Origin},
719
		Attestations: attestations::{Module, Call, Storage},
Gavin Wood's avatar
Gavin Wood committed
720
		Slots: slots::{Module, Call, Storage, Event<T>},
721
		Registrar: registrar::{Module, Call, Storage, Event, Config<T>},
722

723
724
		// Utility module.
		Utility: utility::{Module, Call, Storage, Event<T>},
725
726
727

		// Less simple identity module.
		Identity: identity::{Module, Call, Storage, Event<T>},
728
729
730
731
732
733

		// Society module.
		Society: society::{Module, Call, Storage, Event<T>},

		// Social recovery module.
		Recovery: recovery::{Module, Call, Storage, Event<T>},
Gavin Wood's avatar
Gavin Wood committed
734
735
736

		// Vesting. Usable initially, but removed once all vesting is finished.
		Vesting: vesting::{Module, Call, Storage, Event<T>, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
737
738
739

		// System scheduler.
		Scheduler: scheduler::{Module, Call, Storage, Event<T>},
Gav's avatar
Gav committed
740
	}
Gavin Wood's avatar
Gavin Wood committed
741
}
742
743

/// The address format for describing accounts.
744
pub type Address = AccountId;
745
/// Block header type as expected by this runtime.
746
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
747
748
749
750
751
752
/// 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>;
753
754
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
755
	RestrictFunctionality,
756
	system::CheckVersion<Runtime>,
757
	system::CheckGenesis<Runtime>,
758
759
760
	system::CheckEra<Runtime>,
	system::CheckNonce<Runtime>,
	system::CheckWeight<Runtime>,
761
	transaction_payment::ChargeTransactionPayment::<Runtime>,
762
763
	registrar::LimitParathreadCommits<Runtime>,
	parachains::ValidateDoubleVoteReports<Runtime>,
764
);
765
/// Unchecked extrinsic type as expected by this runtime.
766
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
767
/// Extrinsic type that has already been checked.
Gav Wood's avatar
Gav Wood committed
768
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
769
/// Executive: handles dispatch to the various modules.
770
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
771

772
773
sp_api::impl_runtime_apis! {
	impl sp_api::Core<Block> for Runtime {
774
775
776
777
778
779
780
		fn version() -> RuntimeVersion {
			VERSION
		}

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

782
783
		fn initialize_block(header: &<Block as BlockT>::Header) {
			Executive::initialize_block(header)
784
785
		}
	}
Gav's avatar
Gav committed
786

787
	impl sp_api::Metadata<Block> for Runtime {
788
789
790
		fn metadata() -> OpaqueMetadata {
			Runtime::metadata().into()
		}
Gav's avatar
Gav committed
791
792
	}

793
	impl block_builder_api::BlockBuilder<Block> for Runtime {
794
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
795
796
797
			Executive::apply_extrinsic(extrinsic)
		}

798
799
		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
800
		}
801

Gavin Wood's avatar
Gavin Wood committed
802
		fn inherent_extrinsics(data: inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
803
			data.create_extrinsics()
804
		}
805

Gavin Wood's avatar
Gavin Wood committed
806
807
808
809
		fn check_inherents(
			block: Block,
			data: inherents::InherentData,
		) -> inherents::CheckInherentsResult {
810
			data.check_extrinsics(&block)
811
		}
812

813
		fn random_seed() -> <Block as BlockT>::Hash {
Ashley's avatar
Ashley committed
814
			RandomnessCollectiveFlip::random_seed()
815
		}
816
817
	}

818
	impl tx_pool_api::runtime_api::TaggedTransactionQueue<Block> for Runtime {
819
820
821
822
823
		fn validate_transaction(
			source: TransactionSource,
			tx: <Block as BlockT>::Extrinsic,
		) -> TransactionValidity {
			Executive::validate_transaction(source, tx)
824
		}
Gav's avatar
Gav committed
825
	}
826

827
	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
828
829
		fn offchain_worker(header: &<Block as BlockT>::Header) {
			Executive::offchain_worker(header)
830
831
832
		}
	}

833
	impl parachain::ParachainHost<Block> for Runtime {
Gav Wood's avatar
Gav Wood committed
834
		fn validators() -> Vec<parachain::ValidatorId> {
835
			Parachains::authorities()
836
837
		}
		fn duty_roster() -> parachain::DutyRoster {
838
			Parachains::calculate_duty_roster().0
839
		}
840
841
		fn active_parachains() -> Vec<(parachain::Id, Option<(parachain::CollatorId, parachain::Retriable)>)> {
			Registrar::active_paras()
842
		}
843
844
845
846
		fn global_validation_schedule() -> parachain::GlobalValidationSchedule {
			Parachains::global_validation_schedule()
		}
		fn local_validation_data(id: parachain::Id) -> Option<parachain::LocalValidationData> {
847
			Parachains::current_local_validation_data(&id)
848
		}
849
		fn parachain_code(id: parachain::Id) -> Option<parachain::ValidationCode> {
850
851
			Parachains::parachain_code(&id)
		}
852
853
854
		fn get_heads(extrinsics: Vec<<Block as BlockT>::Extrinsic>)
			-> Option<Vec<AbridgedCandidateReceipt>>
		{
855
856
857
858
859
860
861
862
863
864
865
866
			extrinsics
				.into_iter()
				.find_map(|ex| match UncheckedExtrinsic::decode(&mut ex.encode().as_slice()) {
					Ok(ex) => match ex.function {
						Call::Parachains(ParachainsCall::set_heads(heads)) => {
							Some(heads.into_iter().map(|c| c.candidate).collect())
						}
						_ => None,
					}
					Err(_) => None,
				})
		}
867
868
869
		fn signing_context() -> SigningContext {
			Parachains::signing_context()
		}
870
	}
871
872

	impl fg_primitives::GrandpaApi<Block> for Runtime {
873
		fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
874
875
876
877
			Grandpa::grandpa_authorities()
		}
	}

878
	impl babe_primitives::BabeApi<Block> for Runtime {
879
		fn configuration() -> babe_primitives::BabeConfiguration {
880
881
882
883
884
885
886
			// 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(),
887
				epoch_length: EpochDuration::get(),
888
				c: PRIMARY_PROBABILITY,
889
				genesis_authorities: Babe::authorities(),
890
				randomness: Babe::randomness(),
891
				secondary_slots: true,
892
			}