lib.rs 50.8 KB
Newer Older
Shawn Tabrizi's avatar
Shawn Tabrizi committed
1
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
Gav's avatar
Gav committed
2
3
4
5
6
7
8
9
10
11
12
13
14
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
15
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
Gav's avatar
Gav committed
16

17
//! The Polkadot runtime. This can be compiled with `#[no_std]`, ready for Wasm.
Gav's avatar
Gav committed
18
19

#![cfg_attr(not(feature = "std"), no_std)]
20
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
21
#![recursion_limit = "256"]
Gav Wood's avatar
Gav Wood committed
22

Albrecht's avatar
Albrecht committed
23
use pallet_transaction_payment::CurrencyAdapter;
24
use sp_std::prelude::*;
Sergey Pepyakin's avatar
Sergey Pepyakin committed
25
use sp_std::collections::btree_map::BTreeMap;
26
use sp_core::u32_trait::{_1, _2, _3, _5};
27
use parity_scale_codec::{Encode, Decode};
28
use primitives::v1::{
29
30
	AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
	CoreState, GroupRotationInfo, Hash, Id, Moment, Nonce, OccupiedCoreAssumption,
31
	PersistedValidationData, Signature, ValidationCode, ValidatorId, ValidatorIndex,
32
	InboundDownwardMessage, InboundHrmpMessage, SessionInfo,
33
};
34
use runtime_common::{
35
	claims, SlowAdjustingFeeUpdate, CurrencyToVote,
36
	impls::DealWithFees,
37
	BlockHashCount, RocksDbWeight, BlockWeights, BlockLength, OffchainSolutionWeightLimit,
38
	ParachainSessionKeyPlaceholder, AssignmentSessionKeyPlaceholder,
39
};
40
use sp_runtime::{
41
	create_runtime_str, generic, impl_opaque_keys, ModuleId,
42
	ApplyExtrinsicResult, KeyTypeId, Percent, Permill, Perbill,
Gavin Wood's avatar
Gavin Wood committed
43
	transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority},
44
	curve::PiecewiseLinear,
45
	traits::{
46
		BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, AccountIdLookup,
Gavin Wood's avatar
Gavin Wood committed
47
		Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
48
	},
Gav Wood's avatar
Gav Wood committed
49
};
50
51
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
52
53
use sp_version::RuntimeVersion;
use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives};
54
#[cfg(any(feature = "std", test))]
55
use sp_version::NativeVersion;
56
57
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
58
use frame_support::{
59
	parameter_types, construct_runtime, RuntimeDebug,
60
	traits::{KeyOwnerProofSystem, Randomness, LockIdentifier, Filter, InstanceFilter},
61
	weights::Weight,
Gavin Wood's avatar
Gavin Wood committed
62
};
63
64
use frame_system::{EnsureRoot, EnsureOneOf};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
65
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
66
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
67
use pallet_session::historical as session_historical;
68
use static_assertions::const_assert;
69

Gav Wood's avatar
Gav Wood committed
70
#[cfg(feature = "std")]
71
pub use pallet_staking::StakerStatus;
72
#[cfg(any(feature = "std", test))]
73
pub use sp_runtime::BuildStorage;
74
75
pub use pallet_timestamp::Call as TimestampCall;
pub use pallet_balances::Call as BalancesCall;
76
77
78

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

81
82
83
// Weights used in the runtime.
mod weights;

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

88
89
90
91
/// Runtime version (Kusama).
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("kusama"),
	impl_name: create_runtime_str!("parity-kusama"),
92
	authoring_version: 2,
93
	spec_version: 2030,
94
	impl_version: 0,
95
	#[cfg(not(feature = "disable-runtime-api"))]
96
	apis: RUNTIME_API_VERSIONS,
97
	#[cfg(feature = "disable-runtime-api")]
98
	apis: version::create_apis_vec![[]],
99
	transaction_version: 4,
100
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
101

102
103
104
105
106
107
108
/// The BABE epoch configuration at genesis.
pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration =
	babe_primitives::BabeEpochConfiguration {
		c: PRIMARY_PROBABILITY,
		allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots
	};

109
110
111
112
113
114
115
116
117
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

118
/// Avoid processing transactions from slots and parachain registrar.
119
120
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
121
122
	fn filter(_: &Call) -> bool {
		true
123
124
125
	}
}

Gavin Wood's avatar
Gavin Wood committed
126
127
128
type MoreThanHalfCouncil = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
129
	pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
130
131
>;

132
parameter_types! {
133
	pub const Version: RuntimeVersion = VERSION;
134
	pub const SS58Prefix: u8 = 2;
135
136
}

137
impl frame_system::Config for Runtime {
138
	type BaseCallFilter = BaseFilter;
139
140
	type BlockWeights = BlockWeights;
	type BlockLength = BlockLength;
141
	type Origin = Origin;
142
	type Call = Call;
Gav Wood's avatar
Gav Wood committed
143
	type Index = Nonce;
144
145
146
147
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
148
	type Lookup = AccountIdLookup<AccountId, ()>;
149
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
Gav's avatar
Gav committed
150
	type Event = Event;
151
	type BlockHashCount = BlockHashCount;
152
	type DbWeight = RocksDbWeight;
153
	type Version = Version;
154
	type PalletInfo = PalletInfo;
155
	type AccountData = pallet_balances::AccountData<Balance>;
156
	type OnNewAccount = ();
157
	type OnKilledAccount = ();
158
	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
159
	type SS58Prefix = SS58Prefix;
160
161
}

162
parameter_types! {
163
164
	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
		BlockWeights::get().max_block;
165
166
167
	pub const MaxScheduledPerBlock: u32 = 50;
}

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

179
parameter_types! {
180
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
181
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
182
183
	pub const ReportLongevity: u64 =
		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
184
185
}

186
impl pallet_babe::Config for Runtime {
187
188
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
189
190

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

	type KeyOwnerProofSystem = Historical;

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

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

	type HandleEquivocation =
206
		pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
207
208

	type WeightInfo = ();
209
210
}

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

215
impl pallet_indices::Config for Runtime {
Gav Wood's avatar
Gav Wood committed
216
	type AccountIndex = AccountIndex;
217
218
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
219
	type Event = Event;
220
	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
Gav Wood's avatar
Gav Wood committed
221
222
}

Gavin Wood's avatar
Gavin Wood committed
223
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
224
	pub const ExistentialDeposit: Balance = 1 * CENTS;
225
	pub const MaxLocks: u32 = 50;
Gavin Wood's avatar
Gavin Wood committed
226
227
}

228
impl pallet_balances::Config for Runtime {
Gav's avatar
Gav committed
229
	type Balance = Balance;
230
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
231
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
232
	type ExistentialDeposit = ExistentialDeposit;
233
	type AccountStore = System;
234
	type MaxLocks = MaxLocks;
235
	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
236
237
238
239
240
241
}

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

242
impl pallet_transaction_payment::Config for Runtime {
Albrecht's avatar
Albrecht committed
243
	type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees<Self>>;
Gavin Wood's avatar
Gavin Wood committed
244
	type TransactionByteFee = TransactionByteFee;
245
	type WeightToFee = WeightToFee;
246
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
Gav's avatar
Gav committed
247
248
}

249
parameter_types! {
250
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
251
}
252
impl pallet_timestamp::Config for Runtime {
253
	type Moment = u64;
254
	type OnTimestampSet = Babe;
255
	type MinimumPeriod = MinimumPeriod;
256
	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
257
258
}

Gavin Wood's avatar
Gavin Wood committed
259
parameter_types! {
260
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
261
262
263
}

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

271
272
273
274
275
276
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

impl_opaque_keys! {
277
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
278
279
280
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
281
282
		pub para_validator: ParachainSessionKeyPlaceholder<Runtime>,
		pub para_assignment: AssignmentSessionKeyPlaceholder<Runtime>,
Gavin Wood's avatar
Gavin Wood committed
283
		pub authority_discovery: AuthorityDiscovery,
284
	}
285
286
}

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

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

304
impl pallet_session::historical::Config for Runtime {
305
306
	type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
307
308
}

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
parameter_types! {
	// no signed phase for now, just unsigned.
	pub const SignedPhase: u32 = 0;
	// NOTE: length of unsigned phase is, for now, different than `ElectionLookahead` to make sure
	// that we won't run OCW threads at the same time with staking.
	pub const UnsignedPhase: u32 = ElectionLookahead::get() / 2;

	// fallback: no need to do on-chain phragmen while we re on a dry-run.
	pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy =
		pallet_election_provider_multi_phase::FallbackStrategy::Nothing;

	pub SolutionImprovementThreshold: Perbill = Perbill::from_rational_approximation(1u32, 10_000);

	// miner configs
	pub MultiPhaseUnsignedPriority: TransactionPriority = StakingUnsignedPriority::get() - 1u64;
	pub const MinerMaxIterations: u32 = 10;
}

impl pallet_election_provider_multi_phase::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
	type SignedPhase = SignedPhase;
	type UnsignedPhase = UnsignedPhase;
	type SolutionImprovementThreshold = MinSolutionScoreBump;
	type MinerMaxIterations = MinerMaxIterations;
	type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
	type MinerTxPriority = MultiPhaseUnsignedPriority;
	type DataProvider = Staking;
	type OnChainAccuracy = Perbill;
	type CompactSolution = pallet_staking::CompactAssignments;
	type Fallback = Fallback;
	type BenchmarkingConfig = ();
341
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
342
343
}

344
345
346
// 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))%`.
347
pallet_staking_reward_curve::build! {
thiolliere's avatar
thiolliere committed
348
349
350
	const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
		min_inflation: 0_025_000,
		max_inflation: 0_100_000,
351
352
353
		// 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
354
355
356
357
358
359
		falloff: 0_050_000,
		max_piece_count: 40,
		test_precision: 0_005_000,
	);
}

360
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
361
	// Six sessions in an era (6 hours).
362
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
363
	// 28 eras for unbonding (7 days).
364
	pub const BondingDuration: pallet_staking::EraIndex = 28;
365
	// 27 eras in which slashes can be cancelled (slightly less than 7 days).
366
	pub const SlashDeferDuration: pallet_staking::EraIndex = 27;
thiolliere's avatar
thiolliere committed
367
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
368
	pub const MaxNominatorRewardedPerValidator: u32 = 128;
369
370
	// quarter of the last session will be for election.
	pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4;
371
372
	pub const MaxIterations: u32 = 10;
	pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
373
}
374

Gavin Wood's avatar
Gavin Wood committed
375
376
377
type SlashCancelOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
378
	pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
379
380
>;

381
impl pallet_staking::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
382
	type Currency = Balances;
383
	type UnixTime = Timestamp;
384
	type CurrencyToVote = CurrencyToVote;
Gavin Wood's avatar
Gavin Wood committed
385
	type RewardRemainder = Treasury;
Gav's avatar
Gav committed
386
	type Event = Event;
387
	type Slash = Treasury;
388
	type Reward = ();
389
390
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
391
	type SlashDeferDuration = SlashDeferDuration;
Gavin Wood's avatar
Gavin Wood committed
392
393
	// A majority of the council or root can cancel the slash.
	type SlashCancelOrigin = SlashCancelOrigin;
394
	type SessionInterface = Self;
thiolliere's avatar
thiolliere committed
395
	type RewardCurve = RewardCurve;
Gavin Wood's avatar
Gavin Wood committed
396
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
397
398
399
	type NextNewSession = Session;
	type ElectionLookahead = ElectionLookahead;
	type Call = Call;
400
	type UnsignedPriority = StakingUnsignedPriority;
401
	type MaxIterations = MaxIterations;
402
	type MinSolutionScoreBump = MinSolutionScoreBump;
403
404
405
	// The unsigned solution weight targeted by the OCW. We set it to the maximum possible value of
	// a single extrinsic.
	type OffchainSolutionWeightLimit = OffchainSolutionWeightLimit;
406
	type ElectionProvider = ElectionProviderMultiPhase;
407
	type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
408
409
}

410
parameter_types! {
411
412
	pub const LaunchPeriod: BlockNumber = 7 * DAYS;
	pub const VotingPeriod: BlockNumber = 7 * DAYS;
413
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
Gavin Wood's avatar
Gavin Wood committed
414
	pub const MinimumDeposit: Balance = 1 * DOLLARS;
415
416
	pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
417
	// One cent: $10,000 / MB
Gavin Wood's avatar
Gavin Wood committed
418
	pub const PreimageByteDeposit: Balance = 10 * MILLICENTS;
419
	pub const InstantAllowed: bool = true;
420
	pub const MaxVotes: u32 = 100;
421
	pub const MaxProposals: u32 = 100;
422
423
}

424
impl pallet_democracy::Config for Runtime {
425
426
	type Proposal = Call;
	type Event = Event;
427
	type Currency = Balances;
428
429
430
431
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
	type MinimumDeposit = MinimumDeposit;
432
	/// A straight majority of the council can decide what their next motion is.
433
	type ExternalOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
434
	/// A majority can have the next scheduled referendum be a straight majority-carries vote.
435
	type ExternalMajorityOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
436
437
	/// A unanimous council can have the next scheduled referendum be a straight default-carries
	/// (NTB) vote.
438
	type ExternalDefaultOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>;
439
440
	/// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote
	/// be tabled immediately and with a shorter voting/enactment period.
441
442
	type FastTrackOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>;
	type InstantOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>;
443
444
	type InstantAllowed = InstantAllowed;
	type FastTrackVotingPeriod = FastTrackVotingPeriod;
445
	// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
446
447
448
449
450
451
452
453
454
455
456
457
458
	type CancellationOrigin = EnsureOneOf<
		AccountId,
		EnsureRoot<AccountId>,
		pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
	>;
	// To cancel a proposal before it has been passed, the technical committee must be unanimous or
	// Root must agree.
	type CancelProposalOrigin = EnsureOneOf<
		AccountId,
		EnsureRoot<AccountId>,
		pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>,
	>;
	type BlacklistOrigin = EnsureRoot<AccountId>;
459
460
	// 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.
461
	type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
462
	type CooloffPeriod = CooloffPeriod;
Gavin Wood's avatar
Gavin Wood committed
463
464
	type PreimageByteDeposit = PreimageByteDeposit;
	type Slash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
465
	type Scheduler = Scheduler;
466
	type PalletsOrigin = OriginCaller;
467
	type MaxVotes = MaxVotes;
468
	type OperationalPreimageOrigin = pallet_collective::EnsureMember<AccountId, CouncilCollective>;
469
470
	type WeightInfo = weights::pallet_democracy::WeightInfo<Runtime>;
	type MaxProposals = MaxProposals;
471
}
472

473
474
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
475
	pub const CouncilMaxProposals: u32 = 100;
476
	pub const CouncilMaxMembers: u32 = 100;
477
478
}

479
type CouncilCollective = pallet_collective::Instance1;
480
impl pallet_collective::Config<CouncilCollective> for Runtime {
481
482
483
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
484
	type MotionDuration = CouncilMotionDuration;
485
	type MaxProposals = CouncilMaxProposals;
486
	type MaxMembers = CouncilMaxMembers;
Wei Tang's avatar
Wei Tang committed
487
	type DefaultVote = pallet_collective::PrimeDefaultVote;
488
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
489
490
}

Gavin Wood's avatar
Gavin Wood committed
491
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
492
	pub const CandidacyBond: Balance = 1 * DOLLARS;
Kian Paimani's avatar
Kian Paimani committed
493
494
495
496
497
	// 1 storage item created, key size is 32 bytes, value size is 16+16.
	pub const VotingBondBase: Balance = deposit(1, 64);
	// additional data per vote is 32 bytes (account id).
	pub const VotingBondFactor: Balance = deposit(0, 32);
	/// Daily council elections
Gavin Wood's avatar
Gavin Wood committed
498
	pub const TermDuration: BlockNumber = 24 * HOURS;
499
500
	pub const DesiredMembers: u32 = 19;
	pub const DesiredRunnersUp: u32 = 19;
501
	pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
502
}
Kian Paimani's avatar
Kian Paimani committed
503

504
505
// Make sure that there are no more than MaxMembers members elected via phragmen.
const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get());
506

507
impl pallet_elections_phragmen::Config for Runtime {
508
	type Event = Event;
509
510
	type Currency = Balances;
	type ChangeMembers = Council;
511
	type InitializeMembers = Council;
512
	type CurrencyToVote = frame_support::traits::U128CurrencyToVote;
Gavin Wood's avatar
Gavin Wood committed
513
	type CandidacyBond = CandidacyBond;
Kian Paimani's avatar
Kian Paimani committed
514
515
	type VotingBondBase = VotingBondBase;
	type VotingBondFactor = VotingBondFactor;
516
517
	type LoserCandidate = Treasury;
	type KickedMember = Treasury;
Gavin Wood's avatar
Gavin Wood committed
518
519
520
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
	type TermDuration = TermDuration;
521
	type ModuleId = ElectionsPhragmenModuleId;
522
	type WeightInfo = weights::pallet_elections_phragmen::WeightInfo<Runtime>;
523
524
}

525
526
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
527
	pub const TechnicalMaxProposals: u32 = 100;
528
	pub const TechnicalMaxMembers: u32 = 100;
529
530
}

531
type TechnicalCollective = pallet_collective::Instance2;
532
impl pallet_collective::Config<TechnicalCollective> for Runtime {
533
534
535
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
536
	type MotionDuration = TechnicalMotionDuration;
537
	type MaxProposals = TechnicalMaxProposals;
538
	type MaxMembers = TechnicalMaxMembers;
Wei Tang's avatar
Wei Tang committed
539
	type DefaultVote = pallet_collective::PrimeDefaultVote;
540
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
541
542
}

543
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
544
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
545
546
547
548
549
	type AddOrigin = MoreThanHalfCouncil;
	type RemoveOrigin = MoreThanHalfCouncil;
	type SwapOrigin = MoreThanHalfCouncil;
	type ResetOrigin = MoreThanHalfCouncil;
	type PrimeOrigin = MoreThanHalfCouncil;
550
551
552
553
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
}

Gavin Wood's avatar
Gavin Wood committed
554
555
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
Gavin Wood's avatar
Gavin Wood committed
556
	pub const ProposalBondMinimum: Balance = 20 * DOLLARS;
557
	pub const SpendPeriod: BlockNumber = 6 * DAYS;
558
	pub const Burn: Permill = Permill::from_perthousand(2);
559
	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
560
561
562
563

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
	pub const TipReportDepositBase: Balance = 1 * DOLLARS;
564
565
566
567
568
569
570
	pub const DataDepositPerByte: Balance = 1 * CENTS;
	pub const BountyDepositBase: Balance = 1 * DOLLARS;
	pub const BountyDepositPayoutDelay: BlockNumber = 4 * DAYS;
	pub const BountyUpdatePeriod: BlockNumber = 90 * DAYS;
	pub const MaximumReasonLength: u32 = 16384;
	pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
	pub const BountyValueMinimum: Balance = 2 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
571
572
}

Gavin Wood's avatar
Gavin Wood committed
573
574
575
type ApproveOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
576
	pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
577
578
>;

579
impl pallet_treasury::Config for Runtime {
580
	type ModuleId = TreasuryModuleId;
Gavin Wood's avatar
Gavin Wood committed
581
	type Currency = Balances;
Gavin Wood's avatar
Gavin Wood committed
582
583
	type ApproveOrigin = ApproveOrigin;
	type RejectOrigin = MoreThanHalfCouncil;
584
	type Event = Event;
585
	type OnSlash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
586
587
588
589
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
590
591
592
593
594
595
596
	type BurnDestination = Society;
	type SpendFunds = Bounties;
	type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
}

impl pallet_bounties::Config for Runtime {
	type Event = Event;
597
598
599
600
601
	type BountyDepositBase = BountyDepositBase;
	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
	type BountyUpdatePeriod = BountyUpdatePeriod;
	type BountyCuratorDeposit = BountyCuratorDeposit;
	type BountyValueMinimum = BountyValueMinimum;
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
	type DataDepositPerByte = DataDepositPerByte;
	type MaximumReasonLength = MaximumReasonLength;
	type WeightInfo = weights::pallet_bounties::WeightInfo<Runtime>;

}

impl pallet_tips::Config for Runtime {
	type Event = Event;
	type DataDepositPerByte = DataDepositPerByte;
	type MaximumReasonLength = MaximumReasonLength;
	type Tippers = ElectionsPhragmen;
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
	type WeightInfo = weights::pallet_tips::WeightInfo<Runtime>;
617
}
618

619
parameter_types! {
620
	pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * BlockWeights::get().max_block;
621
622
}

623
impl pallet_offences::Config for Runtime {
624
	type Event = Event;
625
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
626
	type OnOffenceHandler = Staking;
627
	type WeightSoftLimit = OffencesWeightSoftLimit;
628
629
}

630
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
631

632
633
634
635
parameter_types! {
	pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _;
}

636
parameter_types! {
637
638
	pub StakingUnsignedPriority: TransactionPriority =
		Perbill::from_percent(90) * TransactionPriority::max_value();
639
640
641
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

642
impl pallet_im_online::Config for Runtime {
thiolliere's avatar
thiolliere committed
643
	type AuthorityId = ImOnlineId;
644
	type Event = Event;
645
	type ValidatorSet = Historical;
646
	type ReportUnresponsiveness = Offences;
647
	type SessionDuration = SessionDuration;
648
	type UnsignedPriority = ImOnlineUnsignedPriority;
649
	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
650
651
}

652
impl pallet_grandpa::Config for Runtime {
653
	type Event = Event;
654
655
656
657
658
659
660
661
662
663
664
665
	type Call = Call;

	type KeyOwnerProofSystem = Historical;

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

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

666
667
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
668
669

	type WeightInfo = ();
670
671
}

672
673
/// Submits transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
674
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
675
676
	Call: From<LocalCall>,
{
677
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
678
679
680
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
681
		nonce: <Runtime as frame_system::Config>::Index,
682
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
683
		use sp_runtime::traits::StaticLookup;
684
		// take the biggest period possible.
685
686
687
688
689
690
691
		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>()
692
693
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
694
695
696
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
697
698
699
700
701
702
703
			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),
704
705
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
706
			log::warn!("Unable to create signed payload: {:?}", e);
707
		}).ok()?;
708
709
710
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
711
		let (call, extra, _) = raw_payload.deconstruct();
712
713
		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
		Some((call, (address, signature, extra)))
714
	}
715
716
}

717
impl frame_system::offchain::SigningTypes for Runtime {
718
719
720
721
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

722
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where
723
724
725
726
727
728
	Call: From<C>,
{
	type OverarchingCall = Call;
	type Extrinsic = UncheckedExtrinsic;
}

Gavin Wood's avatar
Gavin Wood committed
729
parameter_types! {
730
	pub Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:";
731
732
}

733
impl claims::Config for Runtime {
734
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
735
	type VestingSchedule = Vesting;
736
	type Prefix = Prefix;
737
	type MoveClaimOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
738
	type WeightInfo = weights::runtime_common_claims::WeightInfo<Runtime>;
739
740
}

741
parameter_types! {
742
	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
Gavin Wood's avatar
Gavin Wood committed
743
744
745
	pub const BasicDeposit: Balance = 10 * DOLLARS;       // 258 bytes on-chain
	pub const FieldDeposit: Balance = 250 * CENTS;        // 66 bytes on-chain
	pub const SubAccountDeposit: Balance = 2 * DOLLARS;   // 53 bytes on-chain
Gavin Wood's avatar
Gavin Wood committed
746
747
	pub const MaxSubAccounts: u32 = 100;
	pub const MaxAdditionalFields: u32 = 100;
748
	pub const MaxRegistrars: u32 = 20;
749
750
}

751
impl pallet_identity::Config for Runtime {
752
753
754
755
756
757
	type Event = Event;
	type Currency = Balances;
	type Slashed = Treasury;
	type BasicDeposit = BasicDeposit;
	type FieldDeposit = FieldDeposit;
	type SubAccountDeposit = SubAccountDeposit;
Gavin Wood's avatar
Gavin Wood committed
758
759
	type MaxSubAccounts = MaxSubAccounts;
	type MaxAdditionalFields = MaxAdditionalFields;
760
	type MaxRegistrars = MaxRegistrars;
Gavin Wood's avatar
Gavin Wood committed
761
762
	type RegistrarOrigin = MoreThanHalfCouncil;
	type ForceOrigin = MoreThanHalfCouncil;
763
	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
764
765
}

766
impl pallet_utility::Config for Runtime {
767
768
	type Event = Event;
	type Call = Call;
769
	type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
770
771
}

Gavin Wood's avatar
Gavin Wood committed
772
parameter_types! {
773
774
	// 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
775
	// Additional storage item size of 32 bytes.
776
	pub const DepositFactor: Balance = deposit(0, 32);
Gavin Wood's avatar
Gavin Wood committed
777
778
779
	pub const MaxSignatories: u16 = 100;
}

780
impl pallet_multisig::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
781
782
783
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
784
785
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
Gavin Wood's avatar
Gavin Wood committed
786
	type MaxSignatories = MaxSignatories;
787
	type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
Gavin Wood's avatar
Gavin Wood committed
788
789
}

790
791
792
793
794
795
796
parameter_types! {
	pub const ConfigDepositBase: Balance = 5 * DOLLARS;
	pub const FriendDepositFactor: Balance = 50 * CENTS;
	pub const MaxFriends: u16 = 9;
	pub const RecoveryDeposit: Balance = 5 * DOLLARS;
}

797
impl pallet_recovery::Config for Runtime {
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
	type ConfigDepositBase = ConfigDepositBase;
	type FriendDepositFactor = FriendDepositFactor;
	type MaxFriends = MaxFriends;
	type RecoveryDeposit = RecoveryDeposit;
}

parameter_types! {
	pub const CandidateDeposit: Balance = 10 * DOLLARS;
	pub const WrongSideDeduction: Balance = 2 * DOLLARS;
	pub const MaxStrikes: u32 = 10;
	pub const RotationPeriod: BlockNumber = 80 * HOURS;
	pub const PeriodSpend: Balance = 500 * DOLLARS;
	pub const MaxLockDuration: BlockNumber = 36 * 30 * DAYS;
	pub const ChallengePeriod: BlockNumber = 7 * DAYS;
815
	pub const SocietyModuleId: ModuleId = ModuleId(*b"py/socie");
816
817
}