lib.rs 48.1 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::{
24
	dummy, claims, SlowAdjustingFeeUpdate,
25
	impls::{CurrencyToVoteHandler, ToAuthor},
26
	NegativeImbalance, BlockHashCount, MaximumBlockWeight, AvailableBlockRatio,
27
	MaximumBlockLength, BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight,
28
	MaximumExtrinsicWeight, purchase, ParachainSessionKeyPlaceholder,
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};
34
use primitives::v1::{
35
	AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
36
};
37
use primitives::v0 as p_v0;
Gavin Wood's avatar
Gavin Wood committed
38
39
40
41
42
43
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,
}};
44
45
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
46
47
use sp_version::RuntimeVersion;
use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives};
48
#[cfg(any(feature = "std", test))]
49
use sp_version::NativeVersion;
50
51
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
52
use frame_support::{
Shawn Tabrizi's avatar
Shawn Tabrizi committed
53
	parameter_types, ord_parameter_types, construct_runtime, debug, RuntimeDebug,
Gavin Wood's avatar
Gavin Wood committed
54
	traits::{KeyOwnerProofSystem, SplitTwoWays, Randomness, LockIdentifier, Filter},
55
	weights::Weight,
Gavin Wood's avatar
Gavin Wood committed
56
};
57
58
use frame_system::{EnsureRoot, EnsureOneOf, EnsureSignedBy};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
59
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
60
61
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
use pallet_session::historical as session_historical;
62
use static_assertions::const_assert;
63

Gav Wood's avatar
Gav Wood committed
64
#[cfg(feature = "std")]
65
pub use pallet_staking::StakerStatus;
66
#[cfg(any(feature = "std", test))]
67
pub use sp_runtime::BuildStorage;
68
69
pub use pallet_timestamp::Call as TimestampCall;
pub use pallet_balances::Call as BalancesCall;
70
71
72

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

76
77
78
// Weights used in the runtime.
mod weights;

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

83
// Polkadot version identifier;
84
/// Runtime version (Polkadot).
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
85
pub const VERSION: RuntimeVersion = RuntimeVersion {
86
87
	spec_name: create_runtime_str!("polkadot"),
	impl_name: create_runtime_str!("parity-polkadot"),
Gavin Wood's avatar
Gavin Wood committed
88
	authoring_version: 0,
89
	spec_version: 24,
90
	impl_version: 0,
91
	#[cfg(not(feature = "disable-runtime-api"))]
92
	apis: RUNTIME_API_VERSIONS,
93
	#[cfg(feature = "disable-runtime-api")]
94
95
	apis: version::create_apis_vec![[]],
	transaction_version: 5,
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
			// Parachains stuff
112
			Call::DummyParachains(_) | Call::DummyAttestations(_) | Call::DummySlots(_) | Call::DummyRegistrar(_) =>
Gavin Wood's avatar
Gavin Wood committed
113
114
115
				false,

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

Gavin Wood's avatar
Gavin Wood committed
131
132
133
type MoreThanHalfCouncil = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
134
	pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
135
136
>;

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

141
impl frame_system::Trait for Runtime {
142
	type BaseCallFilter = BaseFilter;
143
	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 = pallet_balances::AccountData<Balance>;
Gavin Wood's avatar
Gavin Wood committed
164
	type OnNewAccount = ();
165
	type OnKilledAccount = ();
166
	type SystemWeightInfo = weights::frame_system::WeightInfo;
167
168
}

169
impl pallet_scheduler::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
170
171
	type Event = Event;
	type Origin = Origin;
172
	type PalletsOrigin = OriginCaller;
Gavin Wood's avatar
Gavin Wood committed
173
174
	type Call = Call;
	type MaximumWeight = MaximumBlockWeight;
175
	type ScheduleOrigin = EnsureRoot<AccountId>;
176
	type WeightInfo = ();
Gavin Wood's avatar
Gavin Wood committed
177
178
}

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

184
impl pallet_babe::Trait for Runtime {
185
186
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
187
188

	// session module is the trigger
189
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
190
191
192
193
194

	type KeyOwnerProofSystem = Historical;

	type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
195
		pallet_babe::AuthorityId,
196
197
198
199
	)>>::Proof;

	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
200
		pallet_babe::AuthorityId,
201
202
203
	)>>::IdentificationTuple;

	type HandleEquivocation =
204
	pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
205
206
}

Gavin Wood's avatar
Gavin Wood committed
207
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
208
	pub const IndexDeposit: Balance = 10 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
209
210
}

211
impl pallet_indices::Trait for Runtime {
Gav Wood's avatar
Gav Wood committed
212
	type AccountIndex = AccountIndex;
213
214
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
215
	type Event = Event;
216
	type WeightInfo = ();
Gav Wood's avatar
Gav Wood committed
217
218
}

Gavin Wood's avatar
Gavin Wood committed
219
parameter_types! {
220
	pub const ExistentialDeposit: Balance = 100 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
221
222
223
224
225
}

/// Splits fees 80/20 between treasury and block author.
pub type DealWithFees = SplitTwoWays<
	Balance,
226
227
228
	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
229
230
>;

231
impl pallet_balances::Trait for Runtime {
Gav's avatar
Gav committed
232
	type Balance = Balance;
233
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
234
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
235
	type ExistentialDeposit = ExistentialDeposit;
236
	type AccountStore = System;
237
	type WeightInfo = weights::pallet_balances::WeightInfo;
238
239
240
241
242
243
}

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

244
impl pallet_transaction_payment::Trait for Runtime {
245
246
	type Currency = Balances;
	type OnTransactionPayment = DealWithFees;
Gavin Wood's avatar
Gavin Wood committed
247
	type TransactionByteFee = TransactionByteFee;
248
	type WeightToFee = WeightToFee;
249
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
Gav's avatar
Gav committed
250
251
}

252
parameter_types! {
253
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
254
}
255
impl pallet_timestamp::Trait for Runtime {
256
	type Moment = u64;
257
	type OnTimestampSet = Babe;
258
	type MinimumPeriod = MinimumPeriod;
259
	type WeightInfo = weights::pallet_timestamp::WeightInfo;
260
261
}

Gavin Wood's avatar
Gavin Wood committed
262
parameter_types! {
263
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
264
265
266
}

// TODO: substrate#2986 implement this properly
267
268
impl pallet_authorship::Trait for Runtime {
	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
269
270
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
271
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
272
273
}

274
impl_opaque_keys! {
275
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
276
277
278
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
279
		pub parachain_validator: ParachainSessionKeyPlaceholder<Runtime>,
Gavin Wood's avatar
Gavin Wood committed
280
		pub authority_discovery: AuthorityDiscovery,
281
	}
282
283
}

thiolliere's avatar
thiolliere committed
284
285
286
287
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

288
impl pallet_session::Trait for Runtime {
Gav's avatar
Gav committed
289
	type Event = Event;
290
	type ValidatorId = AccountId;
291
	type ValidatorIdOf = pallet_staking::StashOf<Self>;
Gavin Wood's avatar
Gavin Wood committed
292
	type ShouldEndSession = Babe;
293
	type NextSessionRotation = Babe;
294
	type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
Gavin Wood's avatar
Gavin Wood committed
295
296
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
thiolliere's avatar
thiolliere committed
297
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
298
	type WeightInfo = ();
299
300
}

301
302
303
impl pallet_session::historical::Trait for Runtime {
	type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
304
305
}

306
307
308
// 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))%`.
309
pallet_staking_reward_curve::build! {
thiolliere's avatar
thiolliere committed
310
311
312
	const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
		min_inflation: 0_025_000,
		max_inflation: 0_100_000,
313
314
315
		// 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
316
317
318
319
320
321
		falloff: 0_050_000,
		max_piece_count: 40,
		test_precision: 0_005_000,
	);
}

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

Gavin Wood's avatar
Gavin Wood committed
336
337
338
type SlashCancelOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
339
	pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
340
341
>;

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

Gavin Wood's avatar
Gavin Wood committed
367
368
369
370
371
372
373
374
375
376
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;
}

377
impl pallet_identity::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
378
379
380
381
382
383
384
385
386
	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
387
388
	type ForceOrigin = MoreThanHalfCouncil;
	type RegistrarOrigin = MoreThanHalfCouncil;
389
	type WeightInfo = ();
Gavin Wood's avatar
Gavin Wood committed
390
391
}

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

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

459
460
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 7 * DAYS;
461
	pub const CouncilMaxProposals: u32 = 100;
462
	pub const CouncilMaxMembers: u32 = 100;
463
464
}

465
466
type CouncilCollective = pallet_collective::Instance1;
impl pallet_collective::Trait<CouncilCollective> for Runtime {
467
468
469
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
470
	type MotionDuration = CouncilMotionDuration;
471
	type MaxProposals = CouncilMaxProposals;
472
473
	type MaxMembers = CouncilMaxMembers;
	type WeightInfo = weights::pallet_collective::WeightInfo;
474
475
}

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

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

507
508
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 7 * DAYS;
509
	pub const TechnicalMaxProposals: u32 = 100;
510
	pub const TechnicalMaxMembers: u32 = 100;
511
512
}

513
514
type TechnicalCollective = pallet_collective::Instance2;
impl pallet_collective::Trait<TechnicalCollective> for Runtime {
515
516
517
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
518
	type MotionDuration = TechnicalMotionDuration;
519
	type MaxProposals = TechnicalMaxProposals;
520
521
	type MaxMembers = TechnicalMaxMembers;
	type WeightInfo = weights::pallet_collective::WeightInfo;
522
523
}

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

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

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

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

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

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

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

586
impl pallet_authority_discovery::Trait for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
587

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

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

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

606
impl pallet_grandpa::Trait for Runtime {
607
	type Event = Event;
608
609
610
	type Call = Call;

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

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

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

620
	type HandleEquivocation = pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
621
622
}

Gavin Wood's avatar
Gavin Wood committed
623
parameter_types! {
624
625
	pub WindowSize: BlockNumber = pallet_finality_tracker::DEFAULT_WINDOW_SIZE.into();
	pub ReportLatency: BlockNumber = pallet_finality_tracker::DEFAULT_REPORT_LATENCY.into();
Gavin Wood's avatar
Gavin Wood committed
626
627
}

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

634
635
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
636
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
637
638
	Call: From<LocalCall>,
{
639
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
640
641
642
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
643
		nonce: <Runtime as frame_system::Trait>::Index,
644
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
645
		// take the biggest period possible.
646
647
648
649
650
651
652
		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>()
653
654
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
655
656
657
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
658
659
660
661
662
663
664
			frame_system::CheckSpecVersion::<Runtime>::new(),
			frame_system::CheckTxVersion::<Runtime>::new(),
			frame_system::CheckGenesis::<Runtime>::new(),
			frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(period, current_block)),
			frame_system::CheckNonce::<Runtime>::from(nonce),
			frame_system::CheckWeight::<Runtime>::new(),
			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
665
			claims::PrevalidateAttests::<Runtime>::new(),
666
667
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
668
			debug::warn!("Unable to create signed payload: {:?}", e);
669
		}).ok()?;
670
671
672
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
673
674
675
		let (call, extra, _) = raw_payload.deconstruct();
		Some((call, (account, signature, extra)))
	}
676
677
}

678
impl frame_system::offchain::SigningTypes for Runtime {
679
680
681
682
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

683
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where Call: From<C> {
684
	type Extrinsic = UncheckedExtrinsic;
Gavin Wood's avatar
Gavin Wood committed
685
	type OverarchingCall = Call;
686
687
}

688
689
690
691
692
693
parameter_types! {
	pub const ParathreadDeposit: Balance = 500 * DOLLARS;
	pub const QueueSize: usize = 2;
	pub const MaxRetries: u32 = 3;
}

Gavin Wood's avatar
Gavin Wood committed
694
parameter_types! {
695
	pub Prefix: &'static [u8] = b"Pay DOTs to the Polkadot account:";
696
697
698
699
}

impl claims::Trait for Runtime {
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
700
	type VestingSchedule = Vesting;
701
	type Prefix = Prefix;
702
	/// At least 3/4 of the council must agree to a claim move before it can happen.
703
	type MoveClaimOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
704
705
}

706
707
708
709
parameter_types! {
	pub const MinVestedTransfer: Balance = 100 * DOLLARS;
}

710
impl pallet_vesting::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
711
712
713
	type Event = Event;
	type Currency = Balances;
	type BlockNumberToBalance = ConvertInto;
714
	type MinVestedTransfer = MinVestedTransfer;
715
	type WeightInfo = ();
Gavin Wood's avatar
Gavin Wood committed
716
717
}

718
impl pallet_utility::Trait for Runtime {
719
720
	type Event = Event;
	type Call = Call;
721
	type WeightInfo = weights::pallet_utility::WeightInfo;
722
723
}

Gavin Wood's avatar
Gavin Wood committed
724
parameter_types! {
725
726
	// 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
727
	// Additional storage item size of 32 bytes.
728
	pub const DepositFactor: Balance = deposit(0, 32);
Gavin Wood's avatar
Gavin Wood committed
729
730
731
	pub const MaxSignatories: u16 = 100;
}

732
impl pallet_multisig::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
733
734
735
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
736
737
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
Gavin Wood's avatar
Gavin Wood committed
738
	type MaxSignatories = MaxSignatories;
739
	type WeightInfo = ();
Gavin Wood's avatar
Gavin Wood committed
740
741
}

742
743
744
745
746
747
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;
748
749
750
	pub const AnnouncementDepositBase: Balance = deposit(1, 8);
	pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
	pub const MaxPending: u16 = 32;
751
752
}

753
754
impl<I: frame_support::traits::Instance> dummy::Trait<I> for Runtime { }

755
756
757
/// 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
758
759
760
761
762
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
	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());
	}
793
}
Gavin Wood's avatar
Gavin Wood committed
794

795
796
797
798
799
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,
800
801
802
803
804
			ProxyType::NonTransfer => matches!(c,
				Call::System(..) |
				Call::Scheduler(..) |
				Call::Babe(..) |
				Call::Timestamp(..) |
805
806
807
				Call::Indices(pallet_indices::Call::claim(..)) |
				Call::Indices(pallet_indices::Call::free(..)) |
				Call::Indices(pallet_indices::Call::freeze(..)) |
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
				// 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(..) |
824
825
826
827
				Call::DummyParachains(..) |
				Call::DummyAttestations(..) |
				Call::DummySlots(..) |
				Call::DummyRegistrar(..) |
828
				Call::Claims(..) |
829
830
				Call::Vesting(pallet_vesting::Call::vest(..)) |
				Call::Vesting(pallet_vesting::Call::vest_other(..)) |
831
832
833
834
835
				// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
				Call::Utility(..) |
				Call::</