lib.rs 39.3 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 runtime_common::{attestations, claims, parachains, registrar, slots,
24
	impls::{CurrencyToVoteHandler, TargetedFeeAdjustment, ToAuthor},
25
	NegativeImbalance, BlockHashCount, MaximumBlockWeight, AvailableBlockRatio,
26
	MaximumBlockLength, BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight,
Gavin Wood's avatar
Gavin Wood committed
27
	MaximumExtrinsicWeight, TransactionCallFilter,
28
};
Gav Wood's avatar
Gav Wood committed
29

30
use sp_std::prelude::*;
31
use sp_core::u32_trait::{_1, _2, _3, _4, _5};
32
use codec::{Encode, Decode};
33
use primitives::{
34
	AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
Gavin Wood's avatar
Gavin Wood committed
35
	parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext},
36
};
37
use sp_runtime::{
38
	create_runtime_str, generic, impl_opaque_keys, ModuleId,
39
	ApplyExtrinsicResult, KeyTypeId, Percent, Permill, Perbill, Perquintill, PerThing,
40
	transaction_validity::{
Gavin Wood's avatar
Gavin Wood committed
41
		TransactionValidity, TransactionSource, TransactionPriority,
42
	},
43
	curve::PiecewiseLinear,
44
	traits::{
Gavin Wood's avatar
Gavin Wood committed
45
46
		BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, IdentityLookup,
		Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
47
	},
Gav Wood's avatar
Gav Wood committed
48
};
49
50
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
51
use version::RuntimeVersion;
52
use grandpa::{AuthorityId as GrandpaId, fg_primitives};
53
54
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
55
56
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
57
use frame_support::{
58
	parameter_types, construct_runtime, debug, RuntimeDebug,
Gavin Wood's avatar
Gavin Wood committed
59
	traits::{KeyOwnerProofSystem, SplitTwoWays, Randomness, LockIdentifier, Filter},
60
	weights::Weight,
Gavin Wood's avatar
Gavin Wood committed
61
};
thiolliere's avatar
thiolliere committed
62
use im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
63
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
Gavin Wood's avatar
Gavin Wood committed
64
use transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
65
use session::historical as session_historical;
66
use static_assertions::const_assert;
67

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

/// Constant values used within the runtime.
pub mod constants;
79
use constants::{time::*, currency::*, fee::*};
80
use frame_support::traits::InstanceFilter;
81

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

86
// Polkadot version identifier;
87
/// Runtime version (Polkadot).
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
88
pub const VERSION: RuntimeVersion = RuntimeVersion {
89
90
	spec_name: create_runtime_str!("polkadot"),
	impl_name: create_runtime_str!("parity-polkadot"),
Gavin Wood's avatar
Gavin Wood committed
91
	authoring_version: 0,
92
	spec_version: 5,
93
94
	impl_version: 0,
	apis: RUNTIME_API_VERSIONS,
Gavin Wood's avatar
Gavin Wood committed
95
	transaction_version: 0,
96
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
97

98
99
100
101
102
103
104
105
106
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

107
108
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
Gavin Wood's avatar
Gavin Wood committed
109
	fn filter(call: &Call) -> bool {
110
		match call {
Gavin Wood's avatar
Gavin Wood committed
111
			Call::Parachains(parachains::Call::set_heads(..)) => true,
Gavin Wood's avatar
Gavin Wood committed
112

Gavin Wood's avatar
Gavin Wood committed
113
114
115
116
117
118
			// Governance stuff
			Call::Democracy(_) | Call::Council(_) | Call::TechnicalCommittee(_) |
			Call::ElectionsPhragmen(_) | Call::TechnicalMembership(_) | Call::Treasury(_) |
			// Parachains stuff
			Call::Parachains(_) | Call::Attestations(_) | Call::Slots(_) | Call::Registrar(_) |
			// Balances and Vesting's transfer (which can be used to transfer)
Gavin Wood's avatar
Gavin Wood committed
119
120
			Call::Balances(_) | Call::Vesting(vesting::Call::vested_transfer(..)) |
			Call::Indices(indices::Call::transfer(..)) =>
Gavin Wood's avatar
Gavin Wood committed
121
122
123
124
125
126
127
128
				false,

			// These modules are all allowed to be called by transactions:
			Call::System(_) | Call::Scheduler(_) | Call::Indices(_) |
			Call::Babe(_) | Call::Timestamp(_) |
			Call::Authorship(_) | Call::Staking(_) | Call::Offences(_) |
			Call::Session(_) | Call::FinalityTracker(_) | Call::Grandpa(_) | Call::ImOnline(_) |
			Call::AuthorityDiscovery(_) |
Gavin Wood's avatar
Gavin Wood committed
129
			Call::Utility(_) | Call::Claims(_) | Call::Vesting(_) | Call::Sudo(_) |
130
			Call::Identity(_) | Call::Proxy(_) | Call::Multisig(_) =>
Gavin Wood's avatar
Gavin Wood committed
131
				true,
132
133
134
		}
	}
}
135
136
pub struct IsCallable;
frame_support::impl_filter_stack!(IsCallable, BaseFilter, Call, is_callable);
137

138
parameter_types! {
139
	pub const Version: RuntimeVersion = VERSION;
140
141
}

142
143
impl system::Trait for Runtime {
	type Origin = Origin;
144
	type Call = Call;
Gav Wood's avatar
Gav Wood committed
145
	type Index = Nonce;
146
147
148
149
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
150
	type Lookup = IdentityLookup<AccountId>;
151
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
Gav's avatar
Gav committed
152
	type Event = Event;
153
	type BlockHashCount = BlockHashCount;
154
	type MaximumBlockWeight = MaximumBlockWeight;
155
	type DbWeight = RocksDbWeight;
156
157
	type BlockExecutionWeight = BlockExecutionWeight;
	type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
Tomasz Drwięga's avatar
Tomasz Drwięga committed
158
	type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
159
160
	type MaximumBlockLength = MaximumBlockLength;
	type AvailableBlockRatio = AvailableBlockRatio;
161
	type Version = Version;
162
	type ModuleToIndex = ModuleToIndex;
163
	type AccountData = balances::AccountData<Balance>;
Gavin Wood's avatar
Gavin Wood committed
164
	type OnNewAccount = ();
165
	type OnKilledAccount = ();
166
167
}

Gavin Wood's avatar
Gavin Wood committed
168
169
170
171
172
173
174
impl scheduler::Trait for Runtime {
	type Event = Event;
	type Origin = Origin;
	type Call = Call;
	type MaximumWeight = MaximumBlockWeight;
}

175
parameter_types! {
176
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
177
178
179
180
181
182
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
}

impl babe::Trait for Runtime {
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
183
184
185

	// session module is the trigger
	type EpochChangeTrigger = babe::ExternalTrigger;
186
187
}

Gavin Wood's avatar
Gavin Wood committed
188
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
189
	pub const IndexDeposit: Balance = 10 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
190
191
}

Gav Wood's avatar
Gav Wood committed
192
193
impl indices::Trait for Runtime {
	type AccountIndex = AccountIndex;
194
195
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
196
197
198
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
199
parameter_types! {
200
	pub const ExistentialDeposit: Balance = 100 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
201
202
203
204
205
}

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

211
impl balances::Trait for Runtime {
Gav's avatar
Gav committed
212
	type Balance = Balance;
213
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
214
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
215
	type ExistentialDeposit = ExistentialDeposit;
216
	type AccountStore = System;
217
218
219
220
}

parameter_types! {
	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
221
	pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
222
223
}

224
225
226
227
228
229
230
// 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)
);

231
232
233
impl transaction_payment::Trait for Runtime {
	type Currency = Balances;
	type OnTransactionPayment = DealWithFees;
Gavin Wood's avatar
Gavin Wood committed
234
	type TransactionByteFee = TransactionByteFee;
235
	type WeightToFee = WeightToFee;
236
	type FeeMultiplierUpdate = TargetedFeeAdjustment<TargetBlockFullness, Self>;
Gav's avatar
Gav committed
237
238
}

239
parameter_types! {
240
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
241
}
242
impl timestamp::Trait for Runtime {
243
	type Moment = u64;
244
	type OnTimestampSet = Babe;
245
	type MinimumPeriod = MinimumPeriod;
246
247
}

Gavin Wood's avatar
Gavin Wood committed
248
parameter_types! {
249
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
250
251
252
253
}

// TODO: substrate#2986 implement this properly
impl authorship::Trait for Runtime {
254
	type FindAuthor = session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
255
256
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
257
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
258
259
}

260
impl_opaque_keys! {
261
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
262
263
264
265
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
		pub parachain_validator: Parachains,
Gavin Wood's avatar
Gavin Wood committed
266
		pub authority_discovery: AuthorityDiscovery,
267
	}
268
269
}

thiolliere's avatar
thiolliere committed
270
271
272
273
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

274
impl session::Trait for Runtime {
Gav's avatar
Gav committed
275
	type Event = Event;
276
277
	type ValidatorId = AccountId;
	type ValidatorIdOf = staking::StashOf<Self>;
Gavin Wood's avatar
Gavin Wood committed
278
	type ShouldEndSession = Babe;
279
	type NextSessionRotation = Babe;
280
	type SessionManager = session::historical::NoteHistoricalRoot<Self, Staking>;
Gavin Wood's avatar
Gavin Wood committed
281
282
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
thiolliere's avatar
thiolliere committed
283
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
284
285
286
287
}

impl session::historical::Trait for Runtime {
	type FullIdentification = staking::Exposure<AccountId, Balance>;
288
	type FullIdentificationOf = staking::ExposureOf<Runtime>;
289
290
}

291
pallet_staking_reward_curve::build! {
thiolliere's avatar
thiolliere committed
292
293
294
295
296
297
298
299
300
301
	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,
	);
}

302
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
303
	// Six sessions in an era (24 hours).
304
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
305
	// 28 eras for unbonding (28 days).
Gavin Wood's avatar
Gavin Wood committed
306
307
	pub const BondingDuration: staking::EraIndex = 28;
	pub const SlashDeferDuration: staking::EraIndex = 28;
thiolliere's avatar
thiolliere committed
308
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
Gavin Wood's avatar
Gavin Wood committed
309
	pub const MaxNominatorRewardedPerValidator: u32 = 64;
310
	// quarter of the last session will be for election.
Gavin Wood's avatar
Gavin Wood committed
311
	pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 16;
312
313
	pub const MaxIterations: u32 = 10;
	pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
314
}
315

316
impl staking::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
317
	type Currency = Balances;
318
	type UnixTime = Timestamp;
319
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
320
	type RewardRemainder = Treasury;
Gav's avatar
Gav committed
321
	type Event = Event;
322
	type Slash = Treasury;
323
	type Reward = ();
324
325
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
326
327
	type SlashDeferDuration = SlashDeferDuration;
	// A super-majority of the council can cancel the slash.
Gavin Wood's avatar
Gavin Wood committed
328
	type SlashCancelOrigin = collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
329
	type SessionInterface = Self;
thiolliere's avatar
thiolliere committed
330
	type RewardCurve = RewardCurve;
Gavin Wood's avatar
Gavin Wood committed
331
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
332
333
334
	type NextNewSession = Session;
	type ElectionLookahead = ElectionLookahead;
	type Call = Call;
335
	type UnsignedPriority = StakingUnsignedPriority;
336
	type MaxIterations = MaxIterations;
337
	type MinSolutionScoreBump = MinSolutionScoreBump;
338
339
}

Gavin Wood's avatar
Gavin Wood committed
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
parameter_types! {
	// Minimum 4 CENTS/byte
	pub const BasicDeposit: Balance = deposit(1, 258);
	pub const FieldDeposit: Balance = deposit(0, 66);
	pub const SubAccountDeposit: Balance = deposit(1, 53);
	pub const MaxSubAccounts: u32 = 100;
	pub const MaxAdditionalFields: u32 = 100;
	pub const MaxRegistrars: u32 = 20;
}

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

364
parameter_types! {
365
366
	pub const LaunchPeriod: BlockNumber = 28 * DAYS;
	pub const VotingPeriod: BlockNumber = 28 * DAYS;
367
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
368
	pub const MinimumDeposit: Balance = 100 * DOLLARS;
369
370
	pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
371
372
	// One cent: $10,000 / MB
	pub const PreimageByteDeposit: Balance = 1 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
373
	pub const InstantAllowed: bool = true;
374
	pub const MaxVotes: u32 = 100;
375
376
}

377
378
379
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
380
	type Currency = Balances;
381
382
383
384
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
	type MinimumDeposit = MinimumDeposit;
385
386
	/// A straight majority of the council can decide what their next motion is.
	type ExternalOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
387
388
	/// A 60% super-majority can have the next scheduled referendum be a straight majority-carries vote.
	type ExternalMajorityOrigin = collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>;
389
390
391
392
393
394
	/// 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>;
395
396
397
	type InstantOrigin = collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>;
	type InstantAllowed = InstantAllowed;
	type FastTrackVotingPeriod = FastTrackVotingPeriod;
398
399
400
401
402
	// 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>;
403
	type CooloffPeriod = CooloffPeriod;
Gavin Wood's avatar
Gavin Wood committed
404
	type PreimageByteDeposit = PreimageByteDeposit;
Gavin Wood's avatar
Gavin Wood committed
405
	type OperationalPreimageOrigin = collective::EnsureMember<AccountId, CouncilCollective>;
Gavin Wood's avatar
Gavin Wood committed
406
	type Slash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
407
	type Scheduler = Scheduler;
408
	type MaxVotes = MaxVotes;
409
}
410

411
412
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 7 * DAYS;
413
	pub const CouncilMaxProposals: u32 = 100;
414
415
}

416
417
type CouncilCollective = collective::Instance1;
impl collective::Trait<CouncilCollective> for Runtime {
418
419
420
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
421
	type MotionDuration = CouncilMotionDuration;
422
	type MaxProposals = CouncilMaxProposals;
423
424
}

Gavin Wood's avatar
Gavin Wood committed
425
parameter_types! {
426
427
	pub const CandidacyBond: Balance = 100 * DOLLARS;
	pub const VotingBond: Balance = 5 * DOLLARS;
428
429
430
	/// Weekly council elections initially, later monthly.
	pub const TermDuration: BlockNumber = 7 * DAYS;
	/// 13 members initially, to be increased to 23 eventually.
431
	pub const DesiredMembers: u32 = 13;
432
	pub const DesiredRunnersUp: u32 = 20;
433
	pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
434
}
435
// Make sure that there are no more than MAX_MEMBERS members elected via phragmen.
436
const_assert!(DesiredMembers::get() <= collective::MAX_MEMBERS);
437
438

impl elections_phragmen::Trait for Runtime {
439
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
440
	type ModuleId = ElectionsPhragmenModuleId;
441
442
	type Currency = Balances;
	type ChangeMembers = Council;
443
	type InitializeMembers = Council;
444
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
445
446
	type CandidacyBond = CandidacyBond;
	type VotingBond = VotingBond;
447
448
449
	type LoserCandidate = Treasury;
	type BadReport = Treasury;
	type KickedMember = Treasury;
Gavin Wood's avatar
Gavin Wood committed
450
451
452
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
	type TermDuration = TermDuration;
453
454
}

455
456
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 7 * DAYS;
457
	pub const TechnicalMaxProposals: u32 = 100;
458
459
}

460
461
type TechnicalCollective = collective::Instance2;
impl collective::Trait<TechnicalCollective> for Runtime {
462
463
464
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
465
	type MotionDuration = TechnicalMotionDuration;
466
	type MaxProposals = TechnicalMaxProposals;
467
468
}

469
470
471
472
473
474
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>;
475
	type PrimeOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
476
477
478
479
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
}

Gavin Wood's avatar
Gavin Wood committed
480
481
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
482
483
484
	pub const ProposalBondMinimum: Balance = 100 * DOLLARS;
	pub const SpendPeriod: BlockNumber = 24 * DAYS;
	pub const Burn: Permill = Permill::from_percent(1);
485
	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
486
487
488
489
490

	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
491
492
}

493
impl treasury::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
494
	type ModuleId = TreasuryModuleId;
Gavin Wood's avatar
Gavin Wood committed
495
	type Currency = Balances;
496
	type ApproveOrigin = collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>;
497
	type RejectOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
Gavin Wood's avatar
Gavin Wood committed
498
499
500
501
502
	type Tippers = ElectionsPhragmen;
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
	type TipReportDepositPerByte = TipReportDepositPerByte;
503
	type Event = Event;
504
	type ProposalRejection = Treasury;
Gavin Wood's avatar
Gavin Wood committed
505
506
507
508
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
509
}
510

511
parameter_types! {
512
	pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
513
514
}

515
516
517
518
impl offences::Trait for Runtime {
	type Event = Event;
	type IdentificationTuple = session::historical::IdentificationTuple<Self>;
	type OnOffenceHandler = Staking;
519
	type WeightSoftLimit = OffencesWeightSoftLimit;
520
521
}

Gavin Wood's avatar
Gavin Wood committed
522
523
impl authority_discovery::Trait for Runtime {}

524
525
526
527
parameter_types! {
	pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _;
}

528
529
530
531
532
parameter_types! {
	pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

533
impl im_online::Trait for Runtime {
thiolliere's avatar
thiolliere committed
534
	type AuthorityId = ImOnlineId;
535
	type Event = Event;
536
	type SessionDuration = SessionDuration;
Gavin Wood's avatar
Gavin Wood committed
537
	type ReportUnresponsiveness = Offences;
538
	type UnsignedPriority = ImOnlineUnsignedPriority;
539
540
}

541
542
impl grandpa::Trait for Runtime {
	type Event = Event;
543
544
545
546
547
548
549
550
551
552
	type Call = Call;

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

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

Gavin Wood's avatar
Gavin Wood committed
553
554
	type KeyOwnerProofSystem = Historical;

555
556
557
558
559
560
	type HandleEquivocation = grandpa::EquivocationHandler<
		Self::KeyOwnerIdentification,
		primitives::fisherman::FishermanAppCrypto,
		Runtime,
		Offences,
	>;
561
562
}

Gavin Wood's avatar
Gavin Wood committed
563
parameter_types! {
564
565
	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
566
567
568
}

impl finality_tracker::Trait for Runtime {
569
	type OnFinalizationStalled = ();
Gavin Wood's avatar
Gavin Wood committed
570
571
572
573
	type WindowSize = WindowSize;
	type ReportLatency = ReportLatency;
}

574
575
576
577
parameter_types! {
	pub const AttestationPeriod: BlockNumber = 50;
}

578
579
580
impl attestations::Trait for Runtime {
	type AttestationPeriod = AttestationPeriod;
	type ValidatorIdentities = parachains::ValidatorIdentities<Runtime>;
581
	type RewardAttestation = Staking;
582
583
}

584
585
586
parameter_types! {
	pub const MaxCodeSize: u32 = 10 * 1024 * 1024; // 10 MB
	pub const MaxHeadDataSize: u32 = 20 * 1024; // 20 KB
587
588
589
590

	pub const ValidationUpgradeFrequency: BlockNumber = 7 * DAYS;
	pub const ValidationUpgradeDelay: BlockNumber = 1 * DAYS;
	pub const SlashPeriod: BlockNumber = 28 * DAYS;
591
592
}

593
impl parachains::Trait for Runtime {
594
	type AuthorityId = primitives::fisherman::FishermanAppCrypto;
595
596
	type Origin = Origin;
	type Call = Call;
597
	type ParachainCurrency = Balances;
598
	type BlockNumberConversion = sp_runtime::traits::Identity;
599
	type Randomness = RandomnessCollectiveFlip;
600
601
	type ActiveParachains = Registrar;
	type Registrar = Registrar;
602
603
	type MaxCodeSize = MaxCodeSize;
	type MaxHeadDataSize = MaxHeadDataSize;
604
605
606
607
608

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

609
	type Proof = sp_session::MembershipProof;
610
611
612
	type KeyOwnerProofSystem = session::historical::Module<Self>;
	type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple;
	type ReportOffence = Offences;
613
	type BlockHashConversion = sp_runtime::traits::Identity;
614
615
}

616
617
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
618
619
620
621
622
623
624
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,
625
626
		nonce: <Runtime as system::Trait>::Index,
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
627
		// take the biggest period possible.
628
629
630
631
632
633
634
		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>()
635
636
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
637
638
639
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
Gavin Wood's avatar
Gavin Wood committed
640
			TransactionCallFilter::<IsCallable, Call>::new(),
641
642
			system::CheckSpecVersion::<Runtime>::new(),
			system::CheckTxVersion::<Runtime>::new(),
643
644
645
646
647
648
649
			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(),
650
			grandpa::ValidateEquivocationReport::<Runtime>::new(),
651
			claims::PrevalidateAttests::<Runtime>::new(),
652
653
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
654
			debug::warn!("Unable to create signed payload: {:?}", e);
655
		}).ok()?;
656
657
658
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
659
660
661
		let (call, extra, _) = raw_payload.deconstruct();
		Some((call, (account, signature, extra)))
	}
662
663
}

664
665
666
667
668
impl system::offchain::SigningTypes for Runtime {
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

Gavin Wood's avatar
Gavin Wood committed
669
impl<C> system::offchain::SendTransactionTypes<C> for Runtime where Call: From<C> {
670
	type Extrinsic = UncheckedExtrinsic;
Gavin Wood's avatar
Gavin Wood committed
671
	type OverarchingCall = Call;
672
673
}

674
675
676
677
678
679
680
681
682
683
684
685
686
687
parameter_types! {
	pub const ParathreadDeposit: Balance = 500 * DOLLARS;
	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;
688
}
689

Gavin Wood's avatar
Gavin Wood committed
690
parameter_types! {
691
	pub const LeasePeriod: BlockNumber = 100_000;
Gavin Wood's avatar
Gavin Wood committed
692
693
694
695
696
	pub const EndingPeriod: BlockNumber = 1000;
}

impl slots::Trait for Runtime {
	type Event = Event;
697
698
	type Currency = Balances;
	type Parachains = Registrar;
Gavin Wood's avatar
Gavin Wood committed
699
	type EndingPeriod = EndingPeriod;
Gavin Wood's avatar
Gavin Wood committed
700
	type LeasePeriod = LeasePeriod;
701
	type Randomness = RandomnessCollectiveFlip;
Gavin Wood's avatar
Gavin Wood committed
702
703
}

Gavin Wood's avatar
Gavin Wood committed
704
parameter_types! {
705
	pub Prefix: &'static [u8] = b"Pay DOTs to the Polkadot account:";
706
707
708
709
}

impl claims::Trait for Runtime {
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
710
	type VestingSchedule = Vesting;
711
712
713
	type Prefix = Prefix;
}

714
715
716
717
parameter_types! {
	pub const MinVestedTransfer: Balance = 100 * DOLLARS;
}

Gavin Wood's avatar
Gavin Wood committed
718
719
720
721
impl vesting::Trait for Runtime {
	type Event = Event;
	type Currency = Balances;
	type BlockNumberToBalance = ConvertInto;
722
	type MinVestedTransfer = MinVestedTransfer;
Gavin Wood's avatar
Gavin Wood committed
723
724
}

725
726
727
728
729
730
impl utility::Trait for Runtime {
	type Event = Event;
	type Call = Call;
	type IsCallable = IsCallable;
}

Gavin Wood's avatar
Gavin Wood committed
731
parameter_types! {
732
733
	// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
	pub const DepositBase: Balance = deposit(1, 88);
Gavin Wood's avatar
Gavin Wood committed
734
	// Additional storage item size of 32 bytes.
735
	pub const DepositFactor: Balance = deposit(0, 32);
Gavin Wood's avatar
Gavin Wood committed
736
737
738
	pub const MaxSignatories: u16 = 100;
}

739
impl multisig::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
740
741
742
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
743
744
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
Gavin Wood's avatar
Gavin Wood committed
745
746
747
748
	type MaxSignatories = MaxSignatories;
	type IsCallable = IsCallable;
}

749
750
impl sudo::Trait for Runtime {
	type Event = Event;
751
	type Call = Call;
752
753
}

754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
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,
769
	SudoBalances,
770
771
772
773
774
775
776
}
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::NonTransfer => !matches!(c,
777
				Call::Balances(..) | Call::Vesting(vesting::Call::vested_transfer(..))
778
779
780
781
782
					| Call::Indices(indices::Call::transfer(..))
			),
			ProxyType::Governance => matches!(c,
				Call::Democracy(..) | Call::Council(..) | Call::TechnicalCommittee(..)
					| Call::ElectionsPhragmen(..) | Call::Treasury(..)
783
784
785
786
787
788
789
					| Call::Utility(utility::Call::batch(..))
					| Call::Utility(utility::Call::as_limited_sub(..))
			),
			ProxyType::Staking => matches!(c,
				Call::Staking(..) | Call::Utility(utility::Call::batch(..))
					| Call::Utility(utility::Call::as_limited_sub(..))
			),
790
791
792
793
794
			ProxyType::SudoBalances => match c {
				Call::Sudo(sudo::Call::sudo(ref x)) => matches!(x.as_ref(), &Call::Balances(..)),
				Call::Utility(utility::Call::batch(..)) => true,
				_ => false,
			},
795
796
797
798
799
800
801
802
803
		}
	}
	fn is_superset(&self, o: &Self) -> bool {
		match (self, o) {
			(x, y) if x == y => true,
			(ProxyType::Any, _) => true,
			(_, ProxyType::Any) => false,
			(ProxyType::NonTransfer, _) => true,
			_ => false,
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
		}
	}
}

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
819
construct_runtime! {
820
	pub enum Runtime where
821
		Block = Block,
822
		NodeBlock = primitives::Block,
823
		UncheckedExtrinsic = UncheckedExtrinsic
824
	{
825
		// Basic stuff; balances is uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
826
		System: system::{Module, Call, Storage, Config, Event<T>},
Ashley's avatar
Ashley committed
827
		RandomnessCollectiveFlip: randomness_collective_flip::{Module, Storage},
Gavin Wood's avatar
Gavin Wood committed
828
		Scheduler: scheduler::{Module, Call, Storage, Event<T>},
829
830

		// Must be before session.
831
		Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
832
833

		Timestamp: timestamp::{Module, Call, Storage, Inherent},
834
		Indices: indices::{Module, Call, Storage, Config<T>, Event<T>},
835
		Balances: balances::{Module, Call, Storage, Config<T>, Event<T>},
836
		TransactionPayment: transaction_payment::{Module, Storage},
837
838
839

		// Consensus support.
		Authorship: authorship::{Module, Call, Storage},
Kian Paimani's avatar
Kian Paimani committed
840
		Staking: staking::{Module, Call, Storage, Config<T>, Event<T>, ValidateUnsigned},
841
		Offences: offences::{Module, Call, Storage, Event},
842
		Historical: session_historical::{Module},
843
		Session: session::{Module, Call, Storage, Event, Config<T>},
844
		FinalityTracker: finality_tracker::{Module, Call, Storage, Inherent},
845
		Grandpa: grandpa::{Module, Call, Storage, Config, Event},
thiolliere's avatar
thiolliere committed
846
		ImOnline: im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
847
		AuthorityDiscovery: authority_discovery::{Module, Call, Config},
848

Gavin Wood's avatar
Gavin Wood committed
849
850
		// Governance stuff; uncallable initially. Calls should be uncommented once we're ready to
		// enable governance.
Gavin Wood's avatar
Gavin Wood committed
851
		Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
852
853
		Council: collective::<Instance1>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
		TechnicalCommittee: collective::<Instance2>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
854
		ElectionsPhragmen: elections_phragmen::{Module, Call, Storage, Event<T>, Config<T>},
855
		TechnicalMembership: membership::<Instance1>::{Module, Call, Storage, Event<T>, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
856
		Treasury: treasury::{Module, Call, Storage, Event<T>},
857
858

		// Parachains stuff; slots are disabled (no auctions initially). The rest are safe as they
Gavin Wood's avatar
Gavin Wood committed
859
860
		// have no public dispatchables. Disabled `Call` on all of them, but this should be
		// uncommented once we're ready to start parachains.
861
		Parachains: parachains::{Module, Call, Storage, Config, Inherent, Origin},
862
		Attestations: attestations::{Module, Call, Storage},
Gavin Wood's avatar
Gavin Wood committed
863
		Slots: slots::{Module, Call, Storage, Event<T>},
864
		Registrar: registrar::{Module, Call, Storage, Event, Config<T>},
Gavin Wood's avatar
Gavin Wood committed
865
866
867
868
869

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