lib.rs 50.7 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
impl pallet_authorship::Config for Runtime {
264
	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
265
266
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
267
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
268
269
}

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

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

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

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

303
impl pallet_session::historical::Config for Runtime {
304
305
	type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
306
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
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 = ();
340
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
341
342
}

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

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

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

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

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

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

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

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

Gavin Wood's avatar
Gavin Wood committed
490
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
491
	pub const CandidacyBond: Balance = 1 * DOLLARS;
Kian Paimani's avatar
Kian Paimani committed
492
493
494
495
496
	// 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
497
	pub const TermDuration: BlockNumber = 24 * HOURS;
498
499
	pub const DesiredMembers: u32 = 19;
	pub const DesiredRunnersUp: u32 = 19;
500
	pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
501
}
Kian Paimani's avatar
Kian Paimani committed
502

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

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

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

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

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

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

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
	pub const TipReportDepositBase: Balance = 1 * DOLLARS;
563
564
565
566
567
568
569
	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
570
571
}

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

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

impl pallet_bounties::Config for Runtime {
	type Event = Event;
596
597
598
599
600
	type BountyDepositBase = BountyDepositBase;
	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
	type BountyUpdatePeriod = BountyUpdatePeriod;
	type BountyCuratorDeposit = BountyCuratorDeposit;
	type BountyValueMinimum = BountyValueMinimum;
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
	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>;
616
}
617

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

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

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

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

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

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

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

	type KeyOwnerProofSystem = Historical;

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

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

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

	type WeightInfo = ();
669
670
}

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

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

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

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

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

740
parameter_types! {
741
	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
Gavin Wood's avatar
Gavin Wood committed
742
743
744
	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
745
746
	pub const MaxSubAccounts: u32 = 100;
	pub const MaxAdditionalFields: u32 = 100;
747
	pub const MaxRegistrars: u32 = 20;
748
749
}

750
impl pallet_identity::Config for Runtime {
751
752
753
754
755
756
	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
757
758
	type MaxSubAccounts = MaxSubAccounts;
	type MaxAdditionalFields = MaxAdditionalFields;
759
	type MaxRegistrars = MaxRegistrars;
Gavin Wood's avatar
Gavin Wood committed
760
761
	type RegistrarOrigin = MoreThanHalfCouncil;
	type ForceOrigin = MoreThanHalfCouncil;
762
	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
763
764
}

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

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

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

789
790
791
792
793
794
795
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;
}

796
impl pallet_recovery::Config for Runtime {
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
	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;
814
	pub const SocietyModuleId: ModuleId = ModuleId(*b"py/socie");
815
816
}