lib.rs 38.9 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
// 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
15
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
Gav's avatar
Gav committed
16

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,
Gavin Wood's avatar
Gavin Wood committed
28
	parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext},
29
};
30
use runtime_common::{attestations, claims, parachains, registrar, slots,
31
	impls::{CurrencyToVoteHandler, TargetedFeeAdjustment, ToAuthor},
32
	NegativeImbalance, BlockHashCount, MaximumBlockWeight, AvailableBlockRatio,
33
	MaximumBlockLength, BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight,
Gavin Wood's avatar
Gavin Wood committed
34
	MaximumExtrinsicWeight, TransactionCallFilter,
35
};
36
use sp_runtime::{
37
	create_runtime_str, generic, impl_opaque_keys, ModuleId,
38
	ApplyExtrinsicResult, KeyTypeId, Percent, Permill, Perbill, Perquintill, PerThing,
Gavin Wood's avatar
Gavin Wood committed
39
	transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority},
40
	curve::PiecewiseLinear,
41
	traits::{
Gavin Wood's avatar
Gavin Wood committed
42
43
		BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, IdentityLookup,
		Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
44
	},
Gav Wood's avatar
Gav Wood committed
45
};
46
47
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
48
use version::RuntimeVersion;
49
use grandpa::{AuthorityId as GrandpaId, fg_primitives};
50
51
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
52
53
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
54
use frame_support::{
55
56
	parameter_types, construct_runtime, debug, RuntimeDebug,
	traits::{KeyOwnerProofSystem, SplitTwoWays, Randomness, LockIdentifier, Filter, InstanceFilter},
57
	weights::Weight,
Gavin Wood's avatar
Gavin Wood committed
58
};
thiolliere's avatar
thiolliere committed
59
use im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
60
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
Gavin Wood's avatar
Gavin Wood committed
61
use transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
62
use session::{historical as session_historical};
63
use static_assertions::const_assert;
64

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

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

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

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

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

102
/// Avoid processing transactions from slots and parachain registrar.
Gavin Wood's avatar
Gavin Wood committed
103
104
105
106
pub struct IsCallable;
impl Filter<Call> for IsCallable {
	fn filter(call: &Call) -> bool {
		!matches!(call, Call::Slots(_) | Call::Registrar(_))
107
108
109
	}
}

110
parameter_types! {
111
	pub const Version: RuntimeVersion = VERSION;
112
113
}

114
115
impl system::Trait for Runtime {
	type Origin = Origin;
116
	type Call = Call;
Gav Wood's avatar
Gav Wood committed
117
	type Index = Nonce;
118
119
120
121
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
122
	type Lookup = IdentityLookup<Self::AccountId>;
123
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
Gav's avatar
Gav committed
124
	type Event = Event;
125
	type BlockHashCount = BlockHashCount;
126
	type MaximumBlockWeight = MaximumBlockWeight;
127
	type DbWeight = RocksDbWeight;
128
129
	type BlockExecutionWeight = BlockExecutionWeight;
	type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
Tomasz Drwięga's avatar
Tomasz Drwięga committed
130
	type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
131
132
	type MaximumBlockLength = MaximumBlockLength;
	type AvailableBlockRatio = AvailableBlockRatio;
133
	type Version = Version;
134
	type ModuleToIndex = ModuleToIndex;
135
136
	type AccountData = balances::AccountData<Balance>;
	type OnNewAccount = ();
137
	type OnKilledAccount = ();
138
139
}

Gavin Wood's avatar
Gavin Wood committed
140
141
142
143
144
145
146
impl scheduler::Trait for Runtime {
	type Event = Event;
	type Origin = Origin;
	type Call = Call;
	type MaximumWeight = MaximumBlockWeight;
}

147
parameter_types! {
148
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
149
150
151
152
153
154
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
}

impl babe::Trait for Runtime {
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
155
156
157

	// session module is the trigger
	type EpochChangeTrigger = babe::ExternalTrigger;
158
159
}

Gavin Wood's avatar
Gavin Wood committed
160
161
162
163
parameter_types! {
	pub const IndexDeposit: Balance = 1 * DOLLARS;
}

Gav Wood's avatar
Gav Wood committed
164
165
impl indices::Trait for Runtime {
	type AccountIndex = AccountIndex;
166
167
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
168
169
170
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
171
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
172
	pub const ExistentialDeposit: Balance = 1 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
173
174
175
176
177
}

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

183
impl balances::Trait for Runtime {
Gav's avatar
Gav committed
184
	type Balance = Balance;
185
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
186
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
187
	type ExistentialDeposit = ExistentialDeposit;
188
	type AccountStore = System;
189
190
191
192
}

parameter_types! {
	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
193
	pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
194
195
}

196
197
198
199
200
201
202
// for a sane configuration, this should always be less than `AvailableBlockRatio`.
const_assert!(
	TargetBlockFullness::get().deconstruct() <
	(AvailableBlockRatio::get().deconstruct() as <Perquintill as PerThing>::Inner)
		* (<Perquintill as PerThing>::ACCURACY / <Perbill as PerThing>::ACCURACY as <Perquintill as PerThing>::Inner)
);

203
204
205
impl transaction_payment::Trait for Runtime {
	type Currency = Balances;
	type OnTransactionPayment = DealWithFees;
Gavin Wood's avatar
Gavin Wood committed
206
	type TransactionByteFee = TransactionByteFee;
207
	type WeightToFee = WeightToFee;
208
	type FeeMultiplierUpdate = TargetedFeeAdjustment<TargetBlockFullness, Self>;
Gav's avatar
Gav committed
209
210
}

211
parameter_types! {
212
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
213
}
214
impl timestamp::Trait for Runtime {
215
	type Moment = u64;
216
	type OnTimestampSet = Babe;
217
	type MinimumPeriod = MinimumPeriod;
218
219
}

Gavin Wood's avatar
Gavin Wood committed
220
parameter_types! {
221
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
222
223
224
225
}

// TODO: substrate#2986 implement this properly
impl authorship::Trait for Runtime {
226
	type FindAuthor = session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
227
228
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
229
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
230
231
}

232
233
234
235
236
237
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

impl_opaque_keys! {
238
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
239
240
241
242
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
		pub parachain_validator: Parachains,
Gavin Wood's avatar
Gavin Wood committed
243
		pub authority_discovery: AuthorityDiscovery,
244
	}
245
246
}

thiolliere's avatar
thiolliere committed
247
248
249
250
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

251
impl session::Trait for Runtime {
Gav's avatar
Gav committed
252
	type Event = Event;
253
254
	type ValidatorId = AccountId;
	type ValidatorIdOf = staking::StashOf<Self>;
Gavin Wood's avatar
Gavin Wood committed
255
	type ShouldEndSession = Babe;
256
	type NextSessionRotation = Babe;
257
	type SessionManager = session::historical::NoteHistoricalRoot<Self, Staking>;
Gavin Wood's avatar
Gavin Wood committed
258
259
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
thiolliere's avatar
thiolliere committed
260
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
261
262
263
264
}

impl session::historical::Trait for Runtime {
	type FullIdentification = staking::Exposure<AccountId, Balance>;
265
	type FullIdentificationOf = staking::ExposureOf<Runtime>;
266
267
}

268
pallet_staking_reward_curve::build! {
thiolliere's avatar
thiolliere committed
269
270
271
272
273
274
275
276
277
278
	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,
	);
}

279
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
280
	// Six sessions in an era (6 hours).
281
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
282
	// 28 eras for unbonding (7 days).
Gavin Wood's avatar
Gavin Wood committed
283
	pub const BondingDuration: staking::EraIndex = 28;
Gavin Wood's avatar
Gavin Wood committed
284
	// 28 eras in which slashes can be cancelled (7 days).
Gavin Wood's avatar
Gavin Wood committed
285
	pub const SlashDeferDuration: staking::EraIndex = 28;
thiolliere's avatar
thiolliere committed
286
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
Gavin Wood's avatar
Gavin Wood committed
287
	pub const MaxNominatorRewardedPerValidator: u32 = 64;
288
289
	// quarter of the last session will be for election.
	pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4;
290
291
	pub const MaxIterations: u32 = 10;
	pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
292
}
293

294
impl staking::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
295
	type Currency = Balances;
296
	type UnixTime = Timestamp;
297
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
298
	type RewardRemainder = Treasury;
Gav's avatar
Gav committed
299
	type Event = Event;
300
	type Slash = Treasury;
301
	type Reward = ();
302
303
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
304
	type SlashDeferDuration = SlashDeferDuration;
Gavin Wood's avatar
Gavin Wood committed
305
306
	// A majority of the council can cancel the slash.
	type SlashCancelOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
307
	type SessionInterface = Self;
thiolliere's avatar
thiolliere committed
308
	type RewardCurve = RewardCurve;
Gavin Wood's avatar
Gavin Wood committed
309
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
310
311
312
	type NextNewSession = Session;
	type ElectionLookahead = ElectionLookahead;
	type Call = Call;
313
	type UnsignedPriority = StakingUnsignedPriority;
314
	type MaxIterations = MaxIterations;
315
	type MinSolutionScoreBump = MinSolutionScoreBump;
316
317
}

318
parameter_types! {
319
320
	pub const LaunchPeriod: BlockNumber = 7 * DAYS;
	pub const VotingPeriod: BlockNumber = 7 * DAYS;
321
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
Gavin Wood's avatar
Gavin Wood committed
322
	pub const MinimumDeposit: Balance = 1 * DOLLARS;
323
324
	pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
325
	// One cent: $10,000 / MB
Gavin Wood's avatar
Gavin Wood committed
326
	pub const PreimageByteDeposit: Balance = 10 * MILLICENTS;
327
	pub const InstantAllowed: bool = true;
328
	pub const MaxVotes: u32 = 100;
329
330
}

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

365
366
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
367
	pub const CouncilMaxProposals: u32 = 100;
368
369
}

370
371
type CouncilCollective = collective::Instance1;
impl collective::Trait<CouncilCollective> for Runtime {
372
373
374
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
375
	type MotionDuration = CouncilMotionDuration;
376
	type MaxProposals = CouncilMaxProposals;
377
378
}

Gavin Wood's avatar
Gavin Wood committed
379
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
380
381
	pub const CandidacyBond: Balance = 1 * DOLLARS;
	pub const VotingBond: Balance = 5 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
382
383
	/// Daily council elections.
	pub const TermDuration: BlockNumber = 24 * HOURS;
384
	pub const DesiredMembers: u32 = 17;
Kian Paimani's avatar
Kian Paimani committed
385
	pub const DesiredRunnersUp: u32 = 7;
386
	pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
387
}
388
// Make sure that there are no more than MAX_MEMBERS members elected via phragmen.
389
const_assert!(DesiredMembers::get() <= collective::MAX_MEMBERS);
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
	type ModuleId = ElectionsPhragmenModuleId;
406
407
}

408
409
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
410
	pub const TechnicalMaxProposals: u32 = 100;
411
412
}

413
414
type TechnicalCollective = collective::Instance2;
impl collective::Trait<TechnicalCollective> for Runtime {
415
416
417
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
418
	type MotionDuration = TechnicalMotionDuration;
419
	type MaxProposals = TechnicalMaxProposals;
420
421
}

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

Gavin Wood's avatar
Gavin Wood committed
433
434
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
Gavin Wood's avatar
Gavin Wood committed
435
	pub const ProposalBondMinimum: Balance = 20 * DOLLARS;
436
	pub const SpendPeriod: BlockNumber = 6 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
437
	pub const Burn: Permill = Permill::from_percent(0);
438
	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
439
440
441
442
443

	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
444
445
}

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

464
parameter_types! {
465
	pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
466
467
}

468
469
470
471
impl offences::Trait for Runtime {
	type Event = Event;
	type IdentificationTuple = session::historical::IdentificationTuple<Self>;
	type OnOffenceHandler = Staking;
472
	type WeightSoftLimit = OffencesWeightSoftLimit;
473
474
}

Gavin Wood's avatar
Gavin Wood committed
475
476
impl authority_discovery::Trait for Runtime {}

477
478
479
480
parameter_types! {
	pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _;
}

481
482
483
484
485
parameter_types! {
	pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

486
impl im_online::Trait for Runtime {
thiolliere's avatar
thiolliere committed
487
	type AuthorityId = ImOnlineId;
488
	type Event = Event;
489
	type ReportUnresponsiveness = Offences;
490
	type SessionDuration = SessionDuration;
491
	type UnsignedPriority = ImOnlineUnsignedPriority;
492
493
}

494
495
impl grandpa::Trait for Runtime {
	type Event = Event;
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
	type Call = Call;

	type KeyOwnerProofSystem = Historical;

	type KeyOwnerProof =
		<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;

	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
		GrandpaId,
	)>>::IdentificationTuple;

	type HandleEquivocation = grandpa::EquivocationHandler<
		Self::KeyOwnerIdentification,
		primitives::fisherman::FishermanAppCrypto,
		Runtime,
		Offences,
	>;
514
515
}

Gavin Wood's avatar
Gavin Wood committed
516
parameter_types! {
517
518
	pub WindowSize: BlockNumber = finality_tracker::DEFAULT_WINDOW_SIZE.into();
	pub ReportLatency: BlockNumber = finality_tracker::DEFAULT_REPORT_LATENCY.into();
Gavin Wood's avatar
Gavin Wood committed
519
520
521
}

impl finality_tracker::Trait for Runtime {
522
	type OnFinalizationStalled = ();
Gavin Wood's avatar
Gavin Wood committed
523
524
525
526
	type WindowSize = WindowSize;
	type ReportLatency = ReportLatency;
}

527
528
529
530
parameter_types! {
	pub const AttestationPeriod: BlockNumber = 50;
}

531
532
533
impl attestations::Trait for Runtime {
	type AttestationPeriod = AttestationPeriod;
	type ValidatorIdentities = parachains::ValidatorIdentities<Runtime>;
534
	type RewardAttestation = Staking;
535
536
}

537
538
539
parameter_types! {
	pub const MaxCodeSize: u32 = 10 * 1024 * 1024; // 10 MB
	pub const MaxHeadDataSize: u32 = 20 * 1024; // 20 KB
540
541
542
	pub const ValidationUpgradeFrequency: BlockNumber = 2 * DAYS;
	pub const ValidationUpgradeDelay: BlockNumber = 8 * HOURS;
	pub const SlashPeriod: BlockNumber = 7 * DAYS;
543
544
}

545
impl parachains::Trait for Runtime {
546
	type AuthorityId = primitives::fisherman::FishermanAppCrypto;
547
548
	type Origin = Origin;
	type Call = Call;
549
	type ParachainCurrency = Balances;
550
	type BlockNumberConversion = sp_runtime::traits::Identity;
551
	type Randomness = RandomnessCollectiveFlip;
552
553
	type ActiveParachains = Registrar;
	type Registrar = Registrar;
554
555
	type MaxCodeSize = MaxCodeSize;
	type MaxHeadDataSize = MaxHeadDataSize;
556
557
558
559
560

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

561
	type Proof = sp_session::MembershipProof;
562
563
564
	type KeyOwnerProofSystem = session::historical::Module<Self>;
	type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple;
	type ReportOffence = Offences;
565
	type BlockHashConversion = sp_runtime::traits::Identity;
566
567
}

568
569
/// Submits transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
570
571
572
573
574
575
576
impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
	Call: From<LocalCall>,
{
	fn create_transaction<C: system::offchain::AppCrypto<Self::Public, Self::Signature>>(
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
577
578
		nonce: <Runtime as system::Trait>::Index,
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
579
		// take the biggest period possible.
580
581
582
583
584
585
586
		let period = BlockHashCount::get()
			.checked_next_power_of_two()
			.map(|c| c / 2)
			.unwrap_or(2) as u64;

		let current_block = System::block_number()
			.saturated_into::<u64>()
587
588
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
589
590
591
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
Gavin Wood's avatar
Gavin Wood committed
592
			TransactionCallFilter::<IsCallable, Call>::new(),
593
594
			system::CheckSpecVersion::<Runtime>::new(),
			system::CheckTxVersion::<Runtime>::new(),
595
596
597
598
599
600
601
			system::CheckGenesis::<Runtime>::new(),
			system::CheckEra::<Runtime>::from(generic::Era::mortal(period, current_block)),
			system::CheckNonce::<Runtime>::from(nonce),
			system::CheckWeight::<Runtime>::new(),
			transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
			registrar::LimitParathreadCommits::<Runtime>::new(),
			parachains::ValidateDoubleVoteReports::<Runtime>::new(),
602
			grandpa::ValidateEquivocationReport::<Runtime>::new(),
603
604
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
605
			debug::warn!("Unable to create signed payload: {:?}", e);
606
		}).ok()?;
607
608
609
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
610
611
612
		let (call, extra, _) = raw_payload.deconstruct();
		Some((call, (account, signature, extra)))
	}
613
614
}

615
616
617
618
619
620
621
622
623
624
625
626
impl system::offchain::SigningTypes for Runtime {
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

impl<C> system::offchain::SendTransactionTypes<C> for Runtime where
	Call: From<C>,
{
	type OverarchingCall = Call;
	type Extrinsic = UncheckedExtrinsic;
}

627
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
628
	pub const ParathreadDeposit: Balance = 5 * DOLLARS;
629
630
631
632
633
634
635
636
637
638
639
640
	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;
641
}
642

Gavin Wood's avatar
Gavin Wood committed
643
parameter_types! {
644
	pub const LeasePeriod: BlockNumber = 100_000;
Gavin Wood's avatar
Gavin Wood committed
645
646
647
648
649
	pub const EndingPeriod: BlockNumber = 1000;
}

impl slots::Trait for Runtime {
	type Event = Event;
650
651
	type Currency = Balances;
	type Parachains = Registrar;
Gavin Wood's avatar
Gavin Wood committed
652
653
	type LeasePeriod = LeasePeriod;
	type EndingPeriod = EndingPeriod;
654
	type Randomness = RandomnessCollectiveFlip;
Gavin Wood's avatar
Gavin Wood committed
655
656
}

Gavin Wood's avatar
Gavin Wood committed
657
parameter_types! {
658
	pub Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:";
659
660
661
662
}

impl claims::Trait for Runtime {
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
663
	type VestingSchedule = Vesting;
664
665
666
	type Prefix = Prefix;
}

667
parameter_types! {
668
	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
Gavin Wood's avatar
Gavin Wood committed
669
670
671
	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
672
673
	pub const MaxSubAccounts: u32 = 100;
	pub const MaxAdditionalFields: u32 = 100;
674
	pub const MaxRegistrars: u32 = 20;
675
676
677
678
679
680
681
682
683
}

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
684
685
	type MaxSubAccounts = MaxSubAccounts;
	type MaxAdditionalFields = MaxAdditionalFields;
686
	type MaxRegistrars = MaxRegistrars;
687
688
689
690
	type RegistrarOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
	type ForceOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
}

Gavin Wood's avatar
Gavin Wood committed
691
692
parameter_types! {
	// One storage item; value is size 4+4+16+32 bytes = 56 bytes.
Gavin Wood's avatar
Gavin Wood committed
693
	pub const MultisigDepositBase: Balance = 30 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
694
	// Additional storage item size of 32 bytes.
Gavin Wood's avatar
Gavin Wood committed
695
	pub const MultisigDepositFactor: Balance = 5 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
696
697
698
699
700
701
702
703
704
705
	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;
Gavin Wood's avatar
Gavin Wood committed
706
	type IsCallable = IsCallable;
Gavin Wood's avatar
Gavin Wood committed
707
708
}

709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
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;
734
	pub const SocietyModuleId: ModuleId = ModuleId(*b"py/socie");
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
}

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;
751
	type ModuleId = SocietyModuleId;
752
753
}

754
755
756
757
parameter_types! {
	pub const MinVestedTransfer: Balance = 100 * DOLLARS;
}

Gavin Wood's avatar
Gavin Wood committed
758
759
760
761
impl vesting::Trait for Runtime {
	type Event = Event;
	type Currency = Balances;
	type BlockNumberToBalance = ConvertInto;
762
	type MinVestedTransfer = MinVestedTransfer;
Gavin Wood's avatar
Gavin Wood committed
763
764
}

765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
parameter_types! {
	// One storage item; key size 32, value size 8; .
	pub const ProxyDepositBase: Balance = deposit(1, 8);
	// Additional storage item size of 33 bytes.
	pub const ProxyDepositFactor: Balance = deposit(0, 33);
	pub const MaxProxies: u16 = 32;
}

/// The type used to represent the kinds of proxying allowed.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)]
pub enum ProxyType {
	Any,
	NonTransfer,
	Governance,
	Staking,
}
impl Default for ProxyType { fn default() -> Self { Self::Any } }
impl InstanceFilter<Call> for ProxyType {
	fn filter(&self, c: &Call) -> bool {
		match self {
			ProxyType::Any => true,
			ProxyType::Governance => matches!(c,
				Call::Democracy(..) | Call::Council(..) | Call::TechnicalCommittee(..)
					| Call::ElectionsPhragmen(..) | Call::Treasury(..)
			),
			ProxyType::NonTransfer => !matches!(c,
				Call::Balances(..) | Call::Utility(..)
					| Call::Vesting(vesting::Call::vested_transfer(..))
					| Call::Indices(indices::Call::transfer(..))
			),
			ProxyType::Staking => matches!(c, Call::Staking(..)),
		}
	}
}

impl proxy::Trait for Runtime {
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
	type IsCallable = IsCallable;
	type ProxyType = ProxyType;
	type ProxyDepositBase = ProxyDepositBase;
	type ProxyDepositFactor = ProxyDepositFactor;
	type MaxProxies = MaxProxies;
}

Gavin Wood's avatar
Gavin Wood committed
811
construct_runtime! {
812
	pub enum Runtime where
813
		Block = Block,
814
		NodeBlock = primitives::Block,
815
		UncheckedExtrinsic = UncheckedExtrinsic
816
	{
817
		// Basic stuff; balances is uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
818
		System: system::{Module, Call, Storage, Config, Event<T>},
Ashley's avatar
Ashley committed
819
		RandomnessCollectiveFlip: randomness_collective_flip::{Module, Storage},
820
821

		// Must be before session.
822
		Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
823
824

		Timestamp: timestamp::{Module, Call, Storage, Inherent},
Gavin Wood's avatar
Gavin Wood committed
825
		Indices: indices::{Module, Call, Storage, Config<T>, Event<T>},
826
		Balances: balances::{Module, Call, Storage, Config<T>, Event<T>},
827
		TransactionPayment: transaction_payment::{Module, Storage},
828
829
830

		// Consensus support.
		Authorship: authorship::{Module, Call, Storage},
Kian Paimani's avatar
Kian Paimani committed
831
		Staking: staking::{Module, Call, Storage, Config<T>, Event<T>, ValidateUnsigned},
832
		Offences: offences::{Module, Call, Storage, Event},
833
		Historical: session_historical::{Module},
834
		Session: session::{Module, Call, Storage, Event, Config<T>},
835
		FinalityTracker: finality_tracker::{Module, Call, Storage, Inherent},
836
		Grandpa: grandpa::{Module, Call, Storage, Config, Event},
thiolliere's avatar
thiolliere committed
837
		ImOnline: im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
838
		AuthorityDiscovery: authority_discovery::{Module, Call, Config},
839
840

		// Governance stuff; uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
841
		Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
842
843
		Council: collective::<Instance1>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
		TechnicalCommittee: collective::<Instance2>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
844
		ElectionsPhragmen: elections_phragmen::{Module, Call, Storage, Event<T>, Config<T>},
845
		TechnicalMembership: membership::<Instance1>::{Module, Call, Storage, Event<T>, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
846
		Treasury: treasury::{Module, Call, Storage, Event<T>},
847
848
849
850
851
852

		// 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.
853
		Parachains: parachains::{Module, Call, Storage, Config, Inherent, Origin},
854
		Attestations: attestations::{Module, Call, Storage},
Gavin Wood's avatar
Gavin Wood committed
855
		Slots: slots::{Module, Call, Storage, Event<T>},
856
		Registrar: registrar::{Module, Call, Storage, Event, Config<T>},
857

858
859
		// Utility module.
		Utility: utility::{Module, Call, Storage, Event<T>},
860
861
862

		// Less simple identity module.
		Identity: identity::{Module, Call, Storage, Event<T>},
863
864
865
866
867
868

		// 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
869
870
871

		// 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
872
873
874

		// System scheduler.
		Scheduler: scheduler::{Module, Call, Storage, Event<T>},
875
876

		// Proxy module. Late addition.
Marcio Diaz's avatar
Marcio Diaz committed
877
		Proxy: proxy::{Module, Call, Storage, Event<T>}
Gav's avatar
Gav committed
878
	}
Gavin Wood's avatar
Gavin Wood committed
879
}
880
881

/// The address format for describing accounts.
882
pub type Address = AccountId;
883
/// Block header type as expected by this runtime.
884
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
885
886
887
888
889
890
/// 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>;
891
892
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
Gavin Wood's avatar
Gavin Wood committed
893
	TransactionCallFilter<IsCallable, Call>,
894
895
	system::CheckSpecVersion<Runtime>,
	system::CheckTxVersion<Runtime>,
896
	system::CheckGenesis<Runtime>,
897
898
899
	system::CheckEra<Runtime>,
	system::CheckNonce<Runtime>,
	system::CheckWeight<Runtime>,
900
	transaction_payment::ChargeTransactionPayment<Runtime>,
901
902
	registrar::LimitParathreadCommits<Runtime>,
	parachains::ValidateDoubleVoteReports<Runtime>,