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

31
use sp_std::prelude::*;
32
use sp_core::u32_trait::{_1, _2, _3, _4, _5};
33
use codec::{Encode, Decode};
asynchronous rob's avatar
asynchronous rob committed
34
35
use primitives::v0::{
	self as parachain,
36
	AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
asynchronous rob's avatar
asynchronous rob committed
37
	ActiveParas, AbridgedCandidateReceipt, SigningContext,
38
};
Gavin Wood's avatar
Gavin Wood committed
39
40
41
42
43
44
use sp_runtime::{create_runtime_str, generic, impl_opaque_keys, ModuleId, ApplyExtrinsicResult, KeyTypeId, Percent, Permill, Perbill, transaction_validity::{
	TransactionValidity, TransactionSource, TransactionPriority,
}, curve::PiecewiseLinear, traits::{
	BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, IdentityLookup,
	Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
}};
45
46
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
47
use version::RuntimeVersion;
48
use grandpa::{AuthorityId as GrandpaId, fg_primitives};
49
50
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
51
52
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
53
use frame_support::{
Shawn Tabrizi's avatar
Shawn Tabrizi committed
54
	parameter_types, ord_parameter_types, construct_runtime, debug, RuntimeDebug,
Gavin Wood's avatar
Gavin Wood committed
55
	traits::{KeyOwnerProofSystem, SplitTwoWays, Randomness, LockIdentifier, Filter},
56
	weights::Weight,
Gavin Wood's avatar
Gavin Wood committed
57
};
Shawn Tabrizi's avatar
Shawn Tabrizi committed
58
use system::{EnsureRoot, EnsureOneOf, EnsureSignedBy};
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
use frame_support::traits::InstanceFilter;
78

79
80
81
// Weights used in the runtime.
mod weights;

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: 23,
93
	impl_version: 0,
94
	#[cfg(not(feature = "disable-runtime-api"))]
95
	apis: RUNTIME_API_VERSIONS,
96
97
	#[cfg(feature = "disable-runtime-api")]
	apis: version::create_apis_vec![[]],
Gavin Wood's avatar
Gavin Wood committed
98
	transaction_version: 4,
99
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
100

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

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

Gavin Wood's avatar
Gavin Wood committed
116
			// Parachains stuff
Gavin Wood's avatar
Gavin Wood committed
117
			Call::Parachains(_) | Call::Attestations(_) | Call::Slots(_) | Call::Registrar(_) =>
Gavin Wood's avatar
Gavin Wood committed
118
119
120
				false,

			// These modules are all allowed to be called by transactions:
121
122
			Call::Democracy(_) | Call::Council(_) | Call::TechnicalCommittee(_) |
			Call::TechnicalMembership(_) | Call::Treasury(_) | Call::ElectionsPhragmen(_) |
Gavin Wood's avatar
Gavin Wood committed
123
			Call::System(_) | Call::Scheduler(_) | Call::Indices(_) |
Gavin Wood's avatar
Gavin Wood committed
124
			Call::Babe(_) | Call::Timestamp(_) | Call::Balances(_) |
Gavin Wood's avatar
Gavin Wood committed
125
126
127
			Call::Authorship(_) | Call::Staking(_) | Call::Offences(_) |
			Call::Session(_) | Call::FinalityTracker(_) | Call::Grandpa(_) | Call::ImOnline(_) |
			Call::AuthorityDiscovery(_) |
Gavin Wood's avatar
Gavin Wood committed
128
			Call::Utility(_) | Call::Claims(_) | Call::Vesting(_) |
Gavin Wood's avatar
Gavin Wood committed
129
			Call::Identity(_) | Call::Proxy(_) | Call::Multisig(_) |
Shawn Tabrizi's avatar
Shawn Tabrizi committed
130
			Call::Purchase(_) =>
Gavin Wood's avatar
Gavin Wood committed
131
				true,
132
133
134
135
		}
	}
}

Gavin Wood's avatar
Gavin Wood committed
136
137
138
139
140
141
type MoreThanHalfCouncil = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
	collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
>;

142
parameter_types! {
143
	pub const Version: RuntimeVersion = VERSION;
144
145
}

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

Gavin Wood's avatar
Gavin Wood committed
174
175
176
impl scheduler::Trait for Runtime {
	type Event = Event;
	type Origin = Origin;
177
	type PalletsOrigin = OriginCaller;
Gavin Wood's avatar
Gavin Wood committed
178
179
	type Call = Call;
	type MaximumWeight = MaximumBlockWeight;
180
	type ScheduleOrigin = EnsureRoot<AccountId>;
181
	type WeightInfo = ();
Gavin Wood's avatar
Gavin Wood committed
182
183
}

184
parameter_types! {
185
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
186
187
188
189
190
191
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
}

impl babe::Trait for Runtime {
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
192
193
194

	// session module is the trigger
	type EpochChangeTrigger = babe::ExternalTrigger;
195
196
197
198
199
200
201
202
203
204
205
206
207
208

	type KeyOwnerProofSystem = Historical;

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

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

	type HandleEquivocation =
Gavin Wood's avatar
Gavin Wood committed
209
	babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
210
211
}

Gavin Wood's avatar
Gavin Wood committed
212
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
213
	pub const IndexDeposit: Balance = 10 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
214
215
}

Gav Wood's avatar
Gav Wood committed
216
217
impl indices::Trait for Runtime {
	type AccountIndex = AccountIndex;
218
219
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
220
	type Event = Event;
221
	type WeightInfo = ();
Gav Wood's avatar
Gav Wood committed
222
223
}

Gavin Wood's avatar
Gavin Wood committed
224
parameter_types! {
225
	pub const ExistentialDeposit: Balance = 100 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
226
227
228
229
230
}

/// Splits fees 80/20 between treasury and block author.
pub type DealWithFees = SplitTwoWays<
	Balance,
231
232
233
	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
234
235
>;

236
impl balances::Trait for Runtime {
Gav's avatar
Gav committed
237
	type Balance = Balance;
238
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
239
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
240
	type ExistentialDeposit = ExistentialDeposit;
241
	type AccountStore = System;
242
	type WeightInfo = weights::balances::WeightInfo;
243
244
245
246
247
248
249
250
251
}

parameter_types! {
	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
}

impl transaction_payment::Trait for Runtime {
	type Currency = Balances;
	type OnTransactionPayment = DealWithFees;
Gavin Wood's avatar
Gavin Wood committed
252
	type TransactionByteFee = TransactionByteFee;
253
	type WeightToFee = WeightToFee;
254
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
Gav's avatar
Gav committed
255
256
}

257
parameter_types! {
258
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
259
}
260
impl timestamp::Trait for Runtime {
261
	type Moment = u64;
262
	type OnTimestampSet = Babe;
263
	type MinimumPeriod = MinimumPeriod;
264
	type WeightInfo = ();
265
266
}

Gavin Wood's avatar
Gavin Wood committed
267
parameter_types! {
268
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
269
270
271
272
}

// TODO: substrate#2986 implement this properly
impl authorship::Trait for Runtime {
273
	type FindAuthor = session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
274
275
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
276
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
277
278
}

279
impl_opaque_keys! {
280
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
281
282
283
284
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
		pub parachain_validator: Parachains,
Gavin Wood's avatar
Gavin Wood committed
285
		pub authority_discovery: AuthorityDiscovery,
286
	}
287
288
}

thiolliere's avatar
thiolliere committed
289
290
291
292
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

293
impl session::Trait for Runtime {
Gav's avatar
Gav committed
294
	type Event = Event;
295
296
	type ValidatorId = AccountId;
	type ValidatorIdOf = staking::StashOf<Self>;
Gavin Wood's avatar
Gavin Wood committed
297
	type ShouldEndSession = Babe;
298
	type NextSessionRotation = Babe;
299
	type SessionManager = session::historical::NoteHistoricalRoot<Self, Staking>;
Gavin Wood's avatar
Gavin Wood committed
300
301
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
thiolliere's avatar
thiolliere committed
302
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
303
	type WeightInfo = ();
304
305
306
307
}

impl session::historical::Trait for Runtime {
	type FullIdentification = staking::Exposure<AccountId, Balance>;
308
	type FullIdentificationOf = staking::ExposureOf<Runtime>;
309
310
}

311
312
313
// TODO #6469: This shouldn't be static, but a lazily cached value, not built unless needed, and
// re-built in case input parameters have changed. The `ideal_stake` should be determined by the
// amount of parachain slots being bid on: this should be around `(75 - 25.min(slots / 4))%`.
314
pallet_staking_reward_curve::build! {
thiolliere's avatar
thiolliere committed
315
316
317
	const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
		min_inflation: 0_025_000,
		max_inflation: 0_100_000,
318
319
320
		// 3:2:1 staked : parachains : float.
		// while there's no parachains, then this is 75% staked : 25% float.
		ideal_stake: 0_750_000,
thiolliere's avatar
thiolliere committed
321
322
323
324
325
326
		falloff: 0_050_000,
		max_piece_count: 40,
		test_precision: 0_005_000,
	);
}

327
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
328
	// Six sessions in an era (24 hours).
329
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
330
	// 28 eras for unbonding (28 days).
Gavin Wood's avatar
Gavin Wood committed
331
	pub const BondingDuration: staking::EraIndex = 28;
332
	pub const SlashDeferDuration: staking::EraIndex = 27;
thiolliere's avatar
thiolliere committed
333
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
Gavin Wood's avatar
Gavin Wood committed
334
	pub const MaxNominatorRewardedPerValidator: u32 = 64;
joe petrowski's avatar
joe petrowski committed
335
	// last 15 minutes of the last session will be for election.
Gavin Wood's avatar
Gavin Wood committed
336
	pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 16;
337
338
	pub const MaxIterations: u32 = 10;
	pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
339
}
340

Gavin Wood's avatar
Gavin Wood committed
341
342
343
344
345
346
type SlashCancelOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
	collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>
>;

347
impl staking::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
348
	type Currency = Balances;
349
	type UnixTime = Timestamp;
350
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
351
	type RewardRemainder = Treasury;
Gav's avatar
Gav committed
352
	type Event = Event;
353
	type Slash = Treasury;
354
	type Reward = ();
355
356
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
357
358
	type SlashDeferDuration = SlashDeferDuration;
	// A super-majority of the council can cancel the slash.
Gavin Wood's avatar
Gavin Wood committed
359
	type SlashCancelOrigin = SlashCancelOrigin;
360
	type SessionInterface = Self;
thiolliere's avatar
thiolliere committed
361
	type RewardCurve = RewardCurve;
Gavin Wood's avatar
Gavin Wood committed
362
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
363
364
365
	type NextNewSession = Session;
	type ElectionLookahead = ElectionLookahead;
	type Call = Call;
366
	type UnsignedPriority = StakingUnsignedPriority;
367
	type MaxIterations = MaxIterations;
368
	type MinSolutionScoreBump = MinSolutionScoreBump;
369
	type WeightInfo = ();
370
371
}

Gavin Wood's avatar
Gavin Wood committed
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
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;
Gavin Wood's avatar
Gavin Wood committed
392
393
	type ForceOrigin = MoreThanHalfCouncil;
	type RegistrarOrigin = MoreThanHalfCouncil;
394
	type WeightInfo = ();
Gavin Wood's avatar
Gavin Wood committed
395
396
}

397
parameter_types! {
398
399
	pub const LaunchPeriod: BlockNumber = 28 * DAYS;
	pub const VotingPeriod: BlockNumber = 28 * DAYS;
400
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
401
	pub const MinimumDeposit: Balance = 100 * DOLLARS;
Gav Wood's avatar
Gav Wood committed
402
	pub const EnactmentPeriod: BlockNumber = 28 * DAYS;
403
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
404
405
	// One cent: $10,000 / MB
	pub const PreimageByteDeposit: Balance = 1 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
406
	pub const InstantAllowed: bool = true;
407
	pub const MaxVotes: u32 = 100;
408
409
}

410
411
412
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
413
	type Currency = Balances;
414
415
416
417
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
	type MinimumDeposit = MinimumDeposit;
418
	/// A straight majority of the council can decide what their next motion is.
Gavin Wood's avatar
Gavin Wood committed
419
420
421
422
	type ExternalOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>,
		system::EnsureRoot<AccountId>,
	>;
423
	/// A 60% super-majority can have the next scheduled referendum be a straight majority-carries vote.
Gavin Wood's avatar
Gavin Wood committed
424
425
426
427
	type ExternalMajorityOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>,
		system::EnsureRoot<AccountId>,
	>;
428
429
	/// A unanimous council can have the next scheduled referendum be a straight default-carries
	/// (NTB) vote.
Gavin Wood's avatar
Gavin Wood committed
430
431
432
433
	type ExternalDefaultOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>,
		system::EnsureRoot<AccountId>,
	>;
434
435
	/// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote
	/// be tabled immediately and with a shorter voting/enactment period.
Gavin Wood's avatar
Gavin Wood committed
436
437
438
439
440
441
442
443
	type FastTrackOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>,
		system::EnsureRoot<AccountId>,
	>;
	type InstantOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>,
		system::EnsureRoot<AccountId>,
	>;
444
445
	type InstantAllowed = InstantAllowed;
	type FastTrackVotingPeriod = FastTrackVotingPeriod;
446
	// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
Gavin Wood's avatar
Gavin Wood committed
447
448
449
450
	type CancellationOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
		system::EnsureRoot<AccountId>,
	>;
451
452
453
	// 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>;
454
	type CooloffPeriod = CooloffPeriod;
Gavin Wood's avatar
Gavin Wood committed
455
	type PreimageByteDeposit = PreimageByteDeposit;
Gavin Wood's avatar
Gavin Wood committed
456
	type OperationalPreimageOrigin = collective::EnsureMember<AccountId, CouncilCollective>;
Gavin Wood's avatar
Gavin Wood committed
457
	type Slash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
458
	type Scheduler = Scheduler;
459
	type PalletsOrigin = OriginCaller;
460
	type MaxVotes = MaxVotes;
461
	type WeightInfo = ();
462
}
463

464
465
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 7 * DAYS;
466
	pub const CouncilMaxProposals: u32 = 100;
467
468
}

469
470
type CouncilCollective = collective::Instance1;
impl collective::Trait<CouncilCollective> for Runtime {
471
472
473
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
474
	type MotionDuration = CouncilMotionDuration;
475
	type MaxProposals = CouncilMaxProposals;
476
	type WeightInfo = ();
477
478
}

Gavin Wood's avatar
Gavin Wood committed
479
parameter_types! {
480
481
	pub const CandidacyBond: Balance = 100 * DOLLARS;
	pub const VotingBond: Balance = 5 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
482
483
	/// Weekly council elections; scaling up to monthly eventually.
	pub const TermDuration: BlockNumber = 7 * DAYS;
484
	/// 13 members initially, to be increased to 23 eventually.
485
	pub const DesiredMembers: u32 = 13;
486
	pub const DesiredRunnersUp: u32 = 20;
487
	pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
488
}
489
// Make sure that there are no more than MAX_MEMBERS members elected via phragmen.
490
const_assert!(DesiredMembers::get() <= collective::MAX_MEMBERS);
491
492

impl elections_phragmen::Trait for Runtime {
493
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
494
	type ModuleId = ElectionsPhragmenModuleId;
495
496
	type Currency = Balances;
	type ChangeMembers = Council;
497
	type InitializeMembers = Council;
498
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
499
500
	type CandidacyBond = CandidacyBond;
	type VotingBond = VotingBond;
501
502
503
	type LoserCandidate = Treasury;
	type BadReport = Treasury;
	type KickedMember = Treasury;
Gavin Wood's avatar
Gavin Wood committed
504
505
506
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
	type TermDuration = TermDuration;
507
	type WeightInfo = ();
508
509
}

510
511
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 7 * DAYS;
512
	pub const TechnicalMaxProposals: u32 = 100;
513
514
}

515
516
type TechnicalCollective = collective::Instance2;
impl collective::Trait<TechnicalCollective> for Runtime {
517
518
519
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
520
	type MotionDuration = TechnicalMotionDuration;
521
	type MaxProposals = TechnicalMaxProposals;
522
	type WeightInfo = ();
523
524
}

525
526
impl membership::Trait<membership::Instance1> for Runtime {
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
527
528
529
530
531
	type AddOrigin = MoreThanHalfCouncil;
	type RemoveOrigin = MoreThanHalfCouncil;
	type SwapOrigin = MoreThanHalfCouncil;
	type ResetOrigin = MoreThanHalfCouncil;
	type PrimeOrigin = MoreThanHalfCouncil;
532
533
534
535
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
}

Gavin Wood's avatar
Gavin Wood committed
536
537
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
538
539
540
	pub const ProposalBondMinimum: Balance = 100 * DOLLARS;
	pub const SpendPeriod: BlockNumber = 24 * DAYS;
	pub const Burn: Permill = Permill::from_percent(1);
541
	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
542
543
544
545
546

	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
547
548
}

Gavin Wood's avatar
Gavin Wood committed
549
550
551
type ApproveOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
Shawn Tabrizi's avatar
Shawn Tabrizi committed
552
	collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
553
554
>;

555
impl treasury::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
556
	type ModuleId = TreasuryModuleId;
Gavin Wood's avatar
Gavin Wood committed
557
	type Currency = Balances;
Gavin Wood's avatar
Gavin Wood committed
558
559
	type ApproveOrigin = ApproveOrigin;
	type RejectOrigin = MoreThanHalfCouncil;
Gavin Wood's avatar
Gavin Wood committed
560
561
562
563
564
	type Tippers = ElectionsPhragmen;
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
	type TipReportDepositPerByte = TipReportDepositPerByte;
565
	type Event = Event;
566
	type ProposalRejection = Treasury;
Gavin Wood's avatar
Gavin Wood committed
567
568
569
570
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
571
	type BurnDestination = ();
572
	type WeightInfo = ();
573
}
574

575
parameter_types! {
576
	pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
577
578
}

579
580
581
582
impl offences::Trait for Runtime {
	type Event = Event;
	type IdentificationTuple = session::historical::IdentificationTuple<Self>;
	type OnOffenceHandler = Staking;
583
	type WeightSoftLimit = OffencesWeightSoftLimit;
584
	type WeightInfo = ();
585
586
}

Gavin Wood's avatar
Gavin Wood committed
587
588
impl authority_discovery::Trait for Runtime {}

589
590
591
592
parameter_types! {
	pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _;
}

593
594
595
596
597
parameter_types! {
	pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

598
impl im_online::Trait for Runtime {
thiolliere's avatar
thiolliere committed
599
	type AuthorityId = ImOnlineId;
600
	type Event = Event;
601
	type SessionDuration = SessionDuration;
Gavin Wood's avatar
Gavin Wood committed
602
	type ReportUnresponsiveness = Offences;
603
	type UnsignedPriority = ImOnlineUnsignedPriority;
604
	type WeightInfo = ();
605
606
}

607
608
impl grandpa::Trait for Runtime {
	type Event = Event;
609
610
611
	type Call = Call;

	type KeyOwnerProof =
Gavin Wood's avatar
Gavin Wood committed
612
	<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
613
614
615
616
617
618

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

Gavin Wood's avatar
Gavin Wood committed
619
620
	type KeyOwnerProofSystem = Historical;

621
	type HandleEquivocation = grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
622
623
}

Gavin Wood's avatar
Gavin Wood committed
624
parameter_types! {
625
626
	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
627
628
629
}

impl finality_tracker::Trait for Runtime {
630
	type OnFinalizationStalled = ();
Gavin Wood's avatar
Gavin Wood committed
631
632
633
634
	type WindowSize = WindowSize;
	type ReportLatency = ReportLatency;
}

635
636
637
638
parameter_types! {
	pub const AttestationPeriod: BlockNumber = 50;
}

639
640
641
impl attestations::Trait for Runtime {
	type AttestationPeriod = AttestationPeriod;
	type ValidatorIdentities = parachains::ValidatorIdentities<Runtime>;
642
	type RewardAttestation = Staking;
643
644
}

645
646
647
parameter_types! {
	pub const MaxCodeSize: u32 = 10 * 1024 * 1024; // 10 MB
	pub const MaxHeadDataSize: u32 = 20 * 1024; // 20 KB
648
649
650
651

	pub const ValidationUpgradeFrequency: BlockNumber = 7 * DAYS;
	pub const ValidationUpgradeDelay: BlockNumber = 1 * DAYS;
	pub const SlashPeriod: BlockNumber = 28 * DAYS;
652
653
}

654
impl parachains::Trait for Runtime {
asynchronous rob's avatar
asynchronous rob committed
655
	type AuthorityId = primitives::v0::fisherman::FishermanAppCrypto;
656
657
	type Origin = Origin;
	type Call = Call;
658
	type ParachainCurrency = Balances;
659
	type BlockNumberConversion = sp_runtime::traits::Identity;
660
	type Randomness = RandomnessCollectiveFlip;
661
662
	type ActiveParachains = Registrar;
	type Registrar = Registrar;
663
664
	type MaxCodeSize = MaxCodeSize;
	type MaxHeadDataSize = MaxHeadDataSize;
665
666
667
668
669

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

670
	type Proof = sp_session::MembershipProof;
671
672
673
	type KeyOwnerProofSystem = session::historical::Module<Self>;
	type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple;
	type ReportOffence = Offences;
674
	type BlockHashConversion = sp_runtime::traits::Identity;
675
676
}

677
678
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
679
680
681
682
683
684
685
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,
686
687
		nonce: <Runtime as system::Trait>::Index,
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
688
		// take the biggest period possible.
689
690
691
692
693
694
695
		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>()
696
697
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
698
699
700
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
701
702
			system::CheckSpecVersion::<Runtime>::new(),
			system::CheckTxVersion::<Runtime>::new(),
703
			system::CheckGenesis::<Runtime>::new(),
704
			system::CheckMortality::<Runtime>::from(generic::Era::mortal(period, current_block)),
705
706
707
708
709
			system::CheckNonce::<Runtime>::from(nonce),
			system::CheckWeight::<Runtime>::new(),
			transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
			registrar::LimitParathreadCommits::<Runtime>::new(),
			parachains::ValidateDoubleVoteReports::<Runtime>::new(),
710
			claims::PrevalidateAttests::<Runtime>::new(),
711
712
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
713
			debug::warn!("Unable to create signed payload: {:?}", e);
714
		}).ok()?;
715
716
717
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
718
719
720
		let (call, extra, _) = raw_payload.deconstruct();
		Some((call, (account, signature, extra)))
	}
721
722
}

723
724
725
726
727
impl system::offchain::SigningTypes for Runtime {
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

Gavin Wood's avatar
Gavin Wood committed
728
impl<C> system::offchain::SendTransactionTypes<C> for Runtime where Call: From<C> {
729
	type Extrinsic = UncheckedExtrinsic;
Gavin Wood's avatar
Gavin Wood committed
730
	type OverarchingCall = Call;
731
732
}

733
734
735
736
737
738
739
740
741
742
743
744
745
746
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;
747
}
748

Gavin Wood's avatar
Gavin Wood committed
749
parameter_types! {
750
	pub const LeasePeriod: BlockNumber = 100_000;
Gavin Wood's avatar
Gavin Wood committed
751
752
753
754
755
	pub const EndingPeriod: BlockNumber = 1000;
}

impl slots::Trait for Runtime {
	type Event = Event;
756
757
	type Currency = Balances;
	type Parachains = Registrar;
Gavin Wood's avatar
Gavin Wood committed
758
	type EndingPeriod = EndingPeriod;
Gavin Wood's avatar
Gavin Wood committed
759
	type LeasePeriod = LeasePeriod;
760
	type Randomness = RandomnessCollectiveFlip;
Gavin Wood's avatar
Gavin Wood committed
761
762
}

Gavin Wood's avatar
Gavin Wood committed
763
parameter_types! {
764
	pub Prefix: &'static [u8] = b"Pay DOTs to the Polkadot account:";
765
766
767
768
}

impl claims::Trait for Runtime {
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
769
	type VestingSchedule = Vesting;
770
	type Prefix = Prefix;
771
772
	/// At least 3/4 of the council must agree to a claim move before it can happen.
	type MoveClaimOrigin = collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
773
774
}

775
776
777
778
parameter_types! {
	pub const MinVestedTransfer: Balance = 100 * DOLLARS;
}

Gavin Wood's avatar
Gavin Wood committed
779
780
781
782
impl vesting::Trait for Runtime {
	type Event = Event;
	type Currency = Balances;
	type BlockNumberToBalance = ConvertInto;
783
	type MinVestedTransfer = MinVestedTransfer;
784
	type WeightInfo = ();
Gavin Wood's avatar
Gavin Wood committed
785
786
}

787
788
789
impl utility::Trait for Runtime {
	type Event = Event;
	type Call = Call;
790
	type WeightInfo = ();
791
792
}

Gavin Wood's avatar
Gavin Wood committed
793
parameter_types! {
794
795
	// 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
796
	// Additional storage item size of 32 bytes.
797
	pub const DepositFactor: Balance = deposit(0, 32);
Gavin Wood's avatar
Gavin Wood committed
798
799
800
	pub const MaxSignatories: u16 = 100;
}

801
impl multisig::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
802
803
804
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
805
806
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
Gavin Wood's avatar
Gavin Wood committed
807
	type MaxSignatories = MaxSignatories;
808
	type WeightInfo = ();
Gavin Wood's avatar
Gavin Wood committed
809
810
}

811
812
813
814
815
816
817
818
819
820
821
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 {
Gavin Wood's avatar
Gavin Wood committed
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
	Any = 0,
	NonTransfer = 1,
	Governance = 2,
	Staking = 3,
	// Skip 4 as it is now removed (was SudoBalances)
	IdentityJudgement = 5,
}

#[cfg(test)]
mod proxt_type_tests {
	use super::*;

	#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)]
	pub enum OldProxyType {
		Any,
		NonTransfer,
		Governance,
		Staking,
		SudoBalances,
		IdentityJudgement,
	}

	#[test]
	fn proxy_type_decodes_correctly() {
		for (i, j) in vec![
			(OldProxyType::Any, ProxyType::Any),
			(OldProxyType::NonTransfer, ProxyType::NonTransfer),
			(OldProxyType::Governance, ProxyType::Governance),
			(OldProxyType::Staking, ProxyType::Staking),
			(OldProxyType::IdentityJudgement, ProxyType::IdentityJudgement),
		].into_iter() {
			assert_eq!(i.encode(), j.encode());
		}
		assert!(ProxyType::decode(&mut &OldProxyType::SudoBalances.encode()[..]).is_err());
	}
857
}
Gavin Wood's avatar
Gavin Wood committed
858

859
860
861
862
863
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,
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
			ProxyType::NonTransfer => matches!(c,
				Call::System(..) |
				Call::Scheduler(..) |
				Call::Babe(..) |
				Call::Timestamp(..) |
				Call::Indices(indices::Call::claim(..)) |
				Call::Indices(indices::Call::free(..)) |
				Call::Indices(indices::Call::freeze(..)) |
				// Specifically omitting Indices `transfer`, `force_transfer`
				// Specifically omitting the entire Balances pallet
				Call::Authorship(..) |
				Call::Staking(..) |
				Call::Offences(..) |
				Call::Session(..) |
				Call::FinalityTracker(..) |
				Call::Grandpa(..) |
				Call::ImOnline(..) |
				Call::AuthorityDiscovery(..) |
				Call::Democracy(..) |
				Call::Council(..) |
				Call::TechnicalCommittee(..) |
				Call::ElectionsPhragmen(..) |
				Call::TechnicalMembership(..) |
				Call::Treasury(..) |
				Call::Parachains(..) |
				Call::Attestations(..) |
				Call::Slots(..) |
				Call::Registrar(..) |
				Call::Claims(..) |
				Call::Vesting(vesting::Call::vest(..)) |
				Call::Vesting(vesting::Call::vest_other(..)) |
				// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
				Call::Utility(..) |
				Call::Identity(..) |
				Call::Proxy(..) |
				Call::Multisig(..)