lib.rs 27 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 rstd::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, CandidateReceipt}, ValidityError,
29
};
30
31
32
33
34
35
use runtime_common::{attestations, claims, parachains, registrar, slots,
	impls::{CurrencyToVoteHandler, TargetedFeeAdjustment, ToAuthor, WeightToFee},
	NegativeImbalance, BlockHashCount, MaximumBlockWeight, AvailableBlockRatio,
	MaximumBlockLength,
};

36
use sp_runtime::{
Gavin Wood's avatar
Gavin Wood committed
37
	create_runtime_str, generic, impl_opaque_keys,
Gavin Wood's avatar
Gavin Wood committed
38
	ApplyExtrinsicResult, Percent, Permill, Perbill, RuntimeDebug,
Gavin Wood's avatar
Gavin Wood committed
39
	transaction_validity::{TransactionValidity, InvalidTransaction, TransactionValidityError},
40
	curve::PiecewiseLinear,
Gavin Wood's avatar
Gavin Wood committed
41
	traits::{BlakeTwo256, Block as BlockT, StaticLookup, SignedExtension, OpaqueKeys},
Gav Wood's avatar
Gav Wood committed
42
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
43
use version::RuntimeVersion;
44
use grandpa::{AuthorityId as GrandpaId, fg_primitives};
45
46
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
47
48
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
49
use frame_support::{
50
51
	parameter_types, construct_runtime, traits::{SplitTwoWays, Randomness},
	weights::DispatchInfo,
Gavin Wood's avatar
Gavin Wood committed
52
};
thiolliere's avatar
thiolliere committed
53
use im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
54
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
Gavin Wood's avatar
Gavin Wood committed
55
use system::offchain::TransactionSubmitter;
56
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
57

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

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

71
72
73
74
// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

75
76
77
78
/// Runtime version (Kusama).
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("kusama"),
	impl_name: create_runtime_str!("parity-kusama"),
79
	authoring_version: 2,
80
81
	spec_version: 1043,
	impl_version: 0,
82
83
	apis: RUNTIME_API_VERSIONS,
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
84

85
86
87
88
89
90
91
92
93
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

94
/// Avoid processing transactions from slots and parachain registrar.
95
#[derive(Default, Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug)]
96
97
pub struct RestrictFunctionality;
impl SignedExtension for RestrictFunctionality {
98
99
100
101
	type AccountId = AccountId;
	type Call = Call;
	type AdditionalSigned = ();
	type Pre = ();
102
103
	type DispatchInfo = DispatchInfo;

Gavin Wood's avatar
Gavin Wood committed
104
	fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) }
105

106
	fn validate(&self, _: &Self::AccountId, call: &Self::Call, _: DispatchInfo, _: usize)
Gavin Wood's avatar
Gavin Wood committed
107
		-> TransactionValidity
108
109
	{
		match call {
Gavin Wood's avatar
Gavin Wood committed
110
			Call::Slots(_) | Call::Registrar(_)
111
112
				=> Err(InvalidTransaction::Custom(ValidityError::NoPermission.into()).into()),
			_ => Ok(Default::default()),
113
114
115
116
		}
	}
}

117
parameter_types! {
118
	pub const Version: RuntimeVersion = VERSION;
119
120
}

121
122
impl system::Trait for Runtime {
	type Origin = Origin;
123
	type Call = Call;
Gav Wood's avatar
Gav Wood committed
124
	type Index = Nonce;
125
126
127
128
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
Gav Wood's avatar
Gav Wood committed
129
	type Lookup = Indices;
130
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
Gav's avatar
Gav committed
131
	type Event = Event;
132
	type BlockHashCount = BlockHashCount;
133
134
135
	type MaximumBlockWeight = MaximumBlockWeight;
	type MaximumBlockLength = MaximumBlockLength;
	type AvailableBlockRatio = AvailableBlockRatio;
136
	type Version = Version;
137
	type ModuleToIndex = ModuleToIndex;
138
139
}

140
parameter_types! {
141
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
142
143
144
145
146
147
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
}

impl babe::Trait for Runtime {
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
148
149
150

	// session module is the trigger
	type EpochChangeTrigger = babe::ExternalTrigger;
151
152
}

Gav Wood's avatar
Gav Wood committed
153
154
155
156
157
158
159
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
160
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
161
	pub const ExistentialDeposit: Balance = 1 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
162
163
164
165
166
167
168
	pub const TransferFee: Balance = 1 * CENTS;
	pub const CreationFee: Balance = 1 * CENTS;
}

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

174
impl balances::Trait for Runtime {
Gav's avatar
Gav committed
175
176
	type Balance = Balance;
	type OnFreeBalanceZero = Staking;
177
	type OnReapAccount = (System, Recovery);
Gav Wood's avatar
Gav Wood committed
178
	type OnNewAccount = Indices;
Gav's avatar
Gav committed
179
	type Event = Event;
180
181
	type DustRemoval = ();
	type TransferPayment = ();
Gavin Wood's avatar
Gavin Wood committed
182
183
184
	type ExistentialDeposit = ExistentialDeposit;
	type TransferFee = TransferFee;
	type CreationFee = CreationFee;
185
186
187
188
189
}

parameter_types! {
	pub const TransactionBaseFee: Balance = 1 * CENTS;
	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
190
191
	// for a sane configuration, this should always be less than `AvailableBlockRatio`.
	pub const TargetBlockFullness: Perbill = Perbill::from_percent(25);
192
193
194
195
196
}

impl transaction_payment::Trait for Runtime {
	type Currency = Balances;
	type OnTransactionPayment = DealWithFees;
Gavin Wood's avatar
Gavin Wood committed
197
198
	type TransactionBaseFee = TransactionBaseFee;
	type TransactionByteFee = TransactionByteFee;
199
	type WeightToFee = WeightToFee;
200
	type FeeMultiplierUpdate = TargetedFeeAdjustment<TargetBlockFullness, Self>;
Gav's avatar
Gav committed
201
202
}

203
parameter_types! {
204
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
205
}
206
impl timestamp::Trait for Runtime {
207
	type Moment = u64;
208
	type OnTimestampSet = Babe;
209
	type MinimumPeriod = MinimumPeriod;
210
211
}

Gavin Wood's avatar
Gavin Wood committed
212
parameter_types! {
213
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
214
215
216
217
}

// TODO: substrate#2986 implement this properly
impl authorship::Trait for Runtime {
218
	type FindAuthor = session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
219
220
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
221
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
222
223
}

224
225
226
227
228
229
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

impl_opaque_keys! {
230
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
231
232
233
234
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
		pub parachain_validator: Parachains,
Gavin Wood's avatar
Gavin Wood committed
235
		pub authority_discovery: AuthorityDiscovery,
236
	}
237
238
}

thiolliere's avatar
thiolliere committed
239
240
241
242
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

243
impl session::Trait for Runtime {
244
	type SessionManager = Staking;
Gavin Wood's avatar
Gavin Wood committed
245
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
246
	type ShouldEndSession = Babe;
Gav's avatar
Gav committed
247
	type Event = Event;
248
	type Keys = SessionKeys;
249
250
	type ValidatorId = AccountId;
	type ValidatorIdOf = staking::StashOf<Self>;
thiolliere's avatar
thiolliere committed
251
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
252
253
254
255
}

impl session::historical::Trait for Runtime {
	type FullIdentification = staking::Exposure<AccountId, Balance>;
256
	type FullIdentificationOf = staking::ExposureOf<Runtime>;
257
258
}

259
pallet_staking_reward_curve::build! {
thiolliere's avatar
thiolliere committed
260
261
262
263
264
265
266
267
268
269
	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,
	);
}

270
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
271
	// Six sessions in an era (6 hours).
272
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
273
	// 28 eras for unbonding (7 days).
Gavin Wood's avatar
Gavin Wood committed
274
	pub const BondingDuration: staking::EraIndex = 28;
Gavin Wood's avatar
Gavin Wood committed
275
	// 28 eras in which slashes can be cancelled (7 days).
Gavin Wood's avatar
Gavin Wood committed
276
	pub const SlashDeferDuration: staking::EraIndex = 28;
thiolliere's avatar
thiolliere committed
277
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
278
}
279

280
impl staking::Trait for Runtime {
281
	type RewardRemainder = Treasury;
282
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gav's avatar
Gav committed
283
	type Event = Event;
284
	type Currency = Balances;
285
	type Slash = Treasury;
286
	type Reward = ();
287
288
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
289
	type SlashDeferDuration = SlashDeferDuration;
Gavin Wood's avatar
Gavin Wood committed
290
291
	// A majority of the council can cancel the slash.
	type SlashCancelOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
292
	type SessionInterface = Self;
293
	type Time = Timestamp;
thiolliere's avatar
thiolliere committed
294
	type RewardCurve = RewardCurve;
295
296
}

297
parameter_types! {
298
299
	pub const LaunchPeriod: BlockNumber = 7 * DAYS;
	pub const VotingPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
300
	pub const EmergencyVotingPeriod: BlockNumber = 3 * HOURS;
Gavin Wood's avatar
Gavin Wood committed
301
	pub const MinimumDeposit: Balance = 1 * DOLLARS;
302
303
	pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
304
	// One cent: $10,000 / MB
Gavin Wood's avatar
Gavin Wood committed
305
	pub const PreimageByteDeposit: Balance = 10 * MILLICENTS;
306
307
}

308
309
310
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
311
	type Currency = Balances;
312
313
314
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
315
	type EmergencyVotingPeriod = EmergencyVotingPeriod;
316
	type MinimumDeposit = MinimumDeposit;
317
318
	/// A straight majority of the council can decide what their next motion is.
	type ExternalOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
319
	/// A majority can have the next scheduled referendum be a straight majority-carries vote.
320
	type ExternalMajorityOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
321
322
323
324
325
326
327
328
329
330
331
	/// 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>;
332
	type CooloffPeriod = CooloffPeriod;
Gavin Wood's avatar
Gavin Wood committed
333
334
	type PreimageByteDeposit = PreimageByteDeposit;
	type Slash = Treasury;
335
}
336

337
338
type CouncilCollective = collective::Instance1;
impl collective::Trait<CouncilCollective> for Runtime {
339
340
341
342
343
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
344
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
345
346
	pub const CandidacyBond: Balance = 1 * DOLLARS;
	pub const VotingBond: Balance = 5 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
347
348
	/// Daily council elections.
	pub const TermDuration: BlockNumber = 24 * HOURS;
Kian Paimani's avatar
Kian Paimani committed
349
350
	pub const DesiredMembers: u32 = 13;
	pub const DesiredRunnersUp: u32 = 7;
351
352
353
}

impl elections_phragmen::Trait for Runtime {
354
	type Event = Event;
355
356
	type Currency = Balances;
	type ChangeMembers = Council;
357
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
358
359
	type CandidacyBond = CandidacyBond;
	type VotingBond = VotingBond;
Kian Paimani's avatar
Kian Paimani committed
360
361
362
	type TermDuration = TermDuration;
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
363
364
365
	type LoserCandidate = Treasury;
	type BadReport = Treasury;
	type KickedMember = Treasury;
366
367
}

368
369
type TechnicalCollective = collective::Instance2;
impl collective::Trait<TechnicalCollective> for Runtime {
370
371
372
373
374
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
}

375
376
377
378
379
380
381
382
383
384
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
385
386
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
Gavin Wood's avatar
Gavin Wood committed
387
	pub const ProposalBondMinimum: Balance = 20 * DOLLARS;
388
	pub const SpendPeriod: BlockNumber = 6 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
389
	pub const Burn: Permill = Permill::from_percent(0);
Gavin Wood's avatar
Gavin Wood committed
390
391
392
393
394

	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
395
396
}

397
impl treasury::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
398
	type Currency = Balances;
399
	type ApproveOrigin = collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>;
400
	type RejectOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
401
	type Event = Event;
402
	type ProposalRejection = Treasury;
Gavin Wood's avatar
Gavin Wood committed
403
404
405
406
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
Gavin Wood's avatar
Gavin Wood committed
407
408
409
410
411
	type Tippers = ElectionsPhragmen;
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
	type TipReportDepositPerByte = TipReportDepositPerByte;
412
}
413

414
415
416
417
418
419
impl offences::Trait for Runtime {
	type Event = Event;
	type IdentificationTuple = session::historical::IdentificationTuple<Self>;
	type OnOffenceHandler = Staking;
}

Gavin Wood's avatar
Gavin Wood committed
420
421
impl authority_discovery::Trait for Runtime {}

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

424
425
426
427
parameter_types! {
	pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _;
}

428
impl im_online::Trait for Runtime {
thiolliere's avatar
thiolliere committed
429
	type AuthorityId = ImOnlineId;
430
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
431
432
	type Call = Call;
	type SubmitTransaction = SubmitTransaction;
433
	type ReportUnresponsiveness = Offences;
434
	type SessionDuration = SessionDuration;
435
436
}

437
438
439
440
impl grandpa::Trait for Runtime {
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
441
442
443
444
445
446
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 {
447
	type OnFinalizationStalled = ();
Gavin Wood's avatar
Gavin Wood committed
448
449
450
451
	type WindowSize = WindowSize;
	type ReportLatency = ReportLatency;
}

452
453
454
455
parameter_types! {
	pub const AttestationPeriod: BlockNumber = 50;
}

456
457
458
impl attestations::Trait for Runtime {
	type AttestationPeriod = AttestationPeriod;
	type ValidatorIdentities = parachains::ValidatorIdentities<Runtime>;
459
	type RewardAttestation = Staking;
460
461
}

462
463
464
impl parachains::Trait for Runtime {
	type Origin = Origin;
	type Call = Call;
465
	type ParachainCurrency = Balances;
466
	type Randomness = RandomnessCollectiveFlip;
467
468
469
470
471
	type ActiveParachains = Registrar;
	type Registrar = Registrar;
}

parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
472
	pub const ParathreadDeposit: Balance = 5 * DOLLARS;
473
474
475
476
477
478
479
480
481
482
483
484
	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;
485
}
486

Gavin Wood's avatar
Gavin Wood committed
487
parameter_types! {
488
	pub const LeasePeriod: BlockNumber = 100_000;
Gavin Wood's avatar
Gavin Wood committed
489
490
491
492
493
	pub const EndingPeriod: BlockNumber = 1000;
}

impl slots::Trait for Runtime {
	type Event = Event;
494
495
	type Currency = Balances;
	type Parachains = Registrar;
Gavin Wood's avatar
Gavin Wood committed
496
497
	type LeasePeriod = LeasePeriod;
	type EndingPeriod = EndingPeriod;
498
	type Randomness = RandomnessCollectiveFlip;
Gavin Wood's avatar
Gavin Wood committed
499
500
}

Gavin Wood's avatar
Gavin Wood committed
501
parameter_types! {
502
503
504
505
506
507
508
509
510
	pub const Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:";
}

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

511
parameter_types! {
512
	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
Gavin Wood's avatar
Gavin Wood committed
513
514
515
	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
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
	pub const MaximumSubAccounts: u32 = 100;
}

impl identity::Trait for Runtime {
	type Event = Event;
	type Currency = Balances;
	type Slashed = Treasury;
	type BasicDeposit = BasicDeposit;
	type FieldDeposit = FieldDeposit;
	type SubAccountDeposit = SubAccountDeposit;
	type MaximumSubAccounts = MaximumSubAccounts;
	type RegistrarOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
	type ForceOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
}

Gavin Wood's avatar
Gavin Wood committed
531
532
parameter_types! {
	// One storage item; value is size 4+4+16+32 bytes = 56 bytes.
Gavin Wood's avatar
Gavin Wood committed
533
	pub const MultisigDepositBase: Balance = 30 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
534
	// Additional storage item size of 32 bytes.
Gavin Wood's avatar
Gavin Wood committed
535
	pub const MultisigDepositFactor: Balance = 5 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
536
537
538
539
540
541
542
543
544
545
546
547
	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;
}

548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
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;
}

Gavin Wood's avatar
Gavin Wood committed
591
construct_runtime! {
592
	pub enum Runtime where
593
		Block = Block,
594
		NodeBlock = primitives::Block,
595
		UncheckedExtrinsic = UncheckedExtrinsic
596
	{
597
		// Basic stuff; balances is uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
598
		System: system::{Module, Call, Storage, Config, Event},
Ashley's avatar
Ashley committed
599
		RandomnessCollectiveFlip: randomness_collective_flip::{Module, Storage},
600
601

		// Must be before session.
602
		Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
603
604

		Timestamp: timestamp::{Module, Call, Storage, Inherent},
Gav Wood's avatar
Gav Wood committed
605
		Indices: indices,
606
		Balances: balances::{Module, Call, Storage, Config<T>, Event<T>},
607
		TransactionPayment: transaction_payment::{Module, Storage},
608
609
610

		// Consensus support.
		Authorship: authorship::{Module, Call, Storage},
611
		Staking: staking,
612
		Offences: offences::{Module, Call, Storage, Event},
613
		Session: session::{Module, Call, Storage, Event, Config<T>},
614
615
		FinalityTracker: finality_tracker::{Module, Call, Inherent},
		Grandpa: grandpa::{Module, Call, Storage, Config, Event},
thiolliere's avatar
thiolliere committed
616
		ImOnline: im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
617
		AuthorityDiscovery: authority_discovery::{Module, Call, Config},
618
619

		// Governance stuff; uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
620
		Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
621
622
		Council: collective::<Instance1>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
		TechnicalCommittee: collective::<Instance2>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
Kian Paimani's avatar
Kian Paimani committed
623
		ElectionsPhragmen: elections_phragmen::{Module, Call, Storage, Event<T>},
624
		TechnicalMembership: membership::<Instance1>::{Module, Call, Storage, Event<T>, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
625
		Treasury: treasury::{Module, Call, Storage, Event<T>},
626
627
628
629
630
631

		// 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.
632
		Parachains: parachains::{Module, Call, Storage, Config, Inherent, Origin},
633
		Attestations: attestations::{Module, Call, Storage},
Gavin Wood's avatar
Gavin Wood committed
634
		Slots: slots::{Module, Call, Storage, Event<T>},
635
		Registrar: registrar::{Module, Call, Storage, Event, Config<T>},
636

637
638
		// Utility module.
		Utility: utility::{Module, Call, Storage, Event<T>},
639
640
641

		// Less simple identity module.
		Identity: identity::{Module, Call, Storage, Event<T>},
642
643
644
645
646
647

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

		// Social recovery module.
		Recovery: recovery::{Module, Call, Storage, Event<T>},
Gav's avatar
Gav committed
648
	}
Gavin Wood's avatar
Gavin Wood committed
649
}
650
651

/// The address format for describing accounts.
Gav Wood's avatar
Gav Wood committed
652
pub type Address = <Indices as StaticLookup>::Source;
653
/// Block header type as expected by this runtime.
654
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
655
656
657
658
659
660
/// 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>;
661
662
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
663
	RestrictFunctionality,
664
	system::CheckVersion<Runtime>,
665
	system::CheckGenesis<Runtime>,
666
667
668
	system::CheckEra<Runtime>,
	system::CheckNonce<Runtime>,
	system::CheckWeight<Runtime>,
669
	transaction_payment::ChargeTransactionPayment::<Runtime>,
670
	registrar::LimitParathreadCommits<Runtime>
671
);
672
/// Unchecked extrinsic type as expected by this runtime.
673
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
674
/// Extrinsic type that has already been checked.
Gav Wood's avatar
Gav Wood committed
675
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
676
/// Executive: handles dispatch to the various modules.
677
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
678

679
680
sp_api::impl_runtime_apis! {
	impl sp_api::Core<Block> for Runtime {
681
682
683
684
685
686
687
		fn version() -> RuntimeVersion {
			VERSION
		}

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

689
690
		fn initialize_block(header: &<Block as BlockT>::Header) {
			Executive::initialize_block(header)
691
692
		}
	}
Gav's avatar
Gav committed
693

694
	impl sp_api::Metadata<Block> for Runtime {
695
696
697
		fn metadata() -> OpaqueMetadata {
			Runtime::metadata().into()
		}
Gav's avatar
Gav committed
698
699
	}

700
	impl block_builder_api::BlockBuilder<Block> for Runtime {
701
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
702
703
704
			Executive::apply_extrinsic(extrinsic)
		}

705
706
		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
707
		}
708

Gavin Wood's avatar
Gavin Wood committed
709
		fn inherent_extrinsics(data: inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
710
			data.create_extrinsics()
711
		}
712

Gavin Wood's avatar
Gavin Wood committed
713
714
715
716
		fn check_inherents(
			block: Block,
			data: inherents::InherentData,
		) -> inherents::CheckInherentsResult {
717
			data.check_extrinsics(&block)
718
		}
719

720
		fn random_seed() -> <Block as BlockT>::Hash {
Ashley's avatar
Ashley committed
721
			RandomnessCollectiveFlip::random_seed()
722
		}
723
724
	}

725
	impl tx_pool_api::runtime_api::TaggedTransactionQueue<Block> for Runtime {
726
727
728
		fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
			Executive::validate_transaction(tx)
		}
Gav's avatar
Gav committed
729
	}
730

731
	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
732
733
		fn offchain_worker(header: &<Block as BlockT>::Header) {
			Executive::offchain_worker(header)
734
735
736
		}
	}

737
	impl parachain::ParachainHost<Block> for Runtime {
Gav Wood's avatar
Gav Wood committed
738
		fn validators() -> Vec<parachain::ValidatorId> {
739
			Parachains::authorities()
740
741
		}
		fn duty_roster() -> parachain::DutyRoster {
742
			Parachains::calculate_duty_roster().0
743
		}
744
745
		fn active_parachains() -> Vec<(parachain::Id, Option<(parachain::CollatorId, parachain::Retriable)>)> {
			Registrar::active_paras()
746
		}
747
748
		fn parachain_status(id: parachain::Id) -> Option<parachain::Status> {
			Parachains::parachain_status(&id)
749
750
751
752
		}
		fn parachain_code(id: parachain::Id) -> Option<Vec<u8>> {
			Parachains::parachain_code(&id)
		}
753
754
755
756
		fn ingress(to: parachain::Id, since: Option<BlockNumber>)
			-> Option<parachain::StructuredUnroutedIngress>
		{
			Parachains::ingress(to, since).map(parachain::StructuredUnroutedIngress)
757
		}
758
759
760
761
762
763
764
765
766
767
768
769
770
		fn get_heads(extrinsics: Vec<<Block as BlockT>::Extrinsic>) -> Option<Vec<CandidateReceipt>> {
			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,
				})
		}
771
	}
772
773

	impl fg_primitives::GrandpaApi<Block> for Runtime {
774
		fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
775
776
777
778
			Grandpa::grandpa_authorities()
		}
	}

779
	impl babe_primitives::BabeApi<Block> for Runtime {
780
		fn configuration() -> babe_primitives::BabeConfiguration {
781
782
783
784
785
786
787
			// 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(),
788
				epoch_length: EpochDuration::get(),
789
				c: PRIMARY_PROBABILITY,
790
				genesis_authorities: Babe::authorities(),
791
				randomness: Babe::randomness(),
792
				secondary_slots: true,
793
			}
794
795
796
		}
	}

Gavin Wood's avatar
Gavin Wood committed
797
798
799
800
801
802
	impl authority_discovery_primitives::AuthorityDiscoveryApi<Block> for Runtime {
		fn authorities() -> Vec<AuthorityDiscoveryId> {
			AuthorityDiscovery::authorities()
		}
	}

Gavin Wood's avatar
Gavin Wood committed
803
	impl sp_session::SessionKeys<Block> for Runtime {
804
805
806
807
		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
			SessionKeys::generate(seed)
		}
	}
808
809
810
811
812
813

	impl system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
		fn account_nonce(account: AccountId) -> Nonce {
			System::account_nonce(account)
		}
	}
Kian Paimani's avatar
Kian Paimani committed
814

815
	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
Kian Paimani's avatar
Kian Paimani committed
816
817
818
819
820
821
822
823
		Block,
		Balance,
		UncheckedExtrinsic,
	> for Runtime {
		fn query_info(uxt: UncheckedExtrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_info(uxt, len)
		}
	}
Gav's avatar
Gav committed
824
}