lib.rs 49.9 KB
Newer Older
Shawn Tabrizi's avatar
Shawn Tabrizi committed
1
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
Gav's avatar
Gav committed
2
3
4
5
6
7
8
9
10
11
12
13
14
// 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: 2029,
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
109
110
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

111
/// Avoid processing transactions from slots and parachain registrar.
112
113
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
114
115
	fn filter(_: &Call) -> bool {
		true
116
117
118
	}
}

Gavin Wood's avatar
Gavin Wood committed
119
120
121
type MoreThanHalfCouncil = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
122
	pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
123
124
>;

125
parameter_types! {
126
	pub const Version: RuntimeVersion = VERSION;
127
	pub const SS58Prefix: u8 = 2;
128
129
}

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

155
parameter_types! {
156
157
	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
		BlockWeights::get().max_block;
158
159
160
	pub const MaxScheduledPerBlock: u32 = 50;
}

161
impl pallet_scheduler::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
162
163
	type Event = Event;
	type Origin = Origin;
164
	type PalletsOrigin = OriginCaller;
Gavin Wood's avatar
Gavin Wood committed
165
	type Call = Call;
166
	type MaximumWeight = MaximumSchedulerWeight;
167
	type ScheduleOrigin = EnsureRoot<AccountId>;
168
	type MaxScheduledPerBlock = MaxScheduledPerBlock;
169
	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
Gavin Wood's avatar
Gavin Wood committed
170
171
}

172
parameter_types! {
173
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
174
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
175
176
	pub const ReportLongevity: u64 =
		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
177
178
}

179
impl pallet_babe::Config for Runtime {
180
181
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
182
183

	// session module is the trigger
184
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
185
186
187
188
189

	type KeyOwnerProofSystem = Historical;

	type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
190
		pallet_babe::AuthorityId,
191
192
193
194
	)>>::Proof;

	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
195
		pallet_babe::AuthorityId,
196
197
198
	)>>::IdentificationTuple;

	type HandleEquivocation =
199
		pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
200
201

	type WeightInfo = ();
202
203
}

Gavin Wood's avatar
Gavin Wood committed
204
205
206
207
parameter_types! {
	pub const IndexDeposit: Balance = 1 * DOLLARS;
}

208
impl pallet_indices::Config for Runtime {
Gav Wood's avatar
Gav Wood committed
209
	type AccountIndex = AccountIndex;
210
211
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
212
	type Event = Event;
213
	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
Gav Wood's avatar
Gav Wood committed
214
215
}

Gavin Wood's avatar
Gavin Wood committed
216
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
217
	pub const ExistentialDeposit: Balance = 1 * CENTS;
218
	pub const MaxLocks: u32 = 50;
Gavin Wood's avatar
Gavin Wood committed
219
220
}

221
impl pallet_balances::Config for Runtime {
Gav's avatar
Gav committed
222
	type Balance = Balance;
223
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
224
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
225
	type ExistentialDeposit = ExistentialDeposit;
226
	type AccountStore = System;
227
	type MaxLocks = MaxLocks;
228
	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
229
230
231
232
233
234
}

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

235
impl pallet_transaction_payment::Config for Runtime {
Albrecht's avatar
Albrecht committed
236
	type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees<Self>>;
Gavin Wood's avatar
Gavin Wood committed
237
	type TransactionByteFee = TransactionByteFee;
238
	type WeightToFee = WeightToFee;
239
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
Gav's avatar
Gav committed
240
241
}

242
parameter_types! {
243
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
244
}
245
impl pallet_timestamp::Config for Runtime {
246
	type Moment = u64;
247
	type OnTimestampSet = Babe;
248
	type MinimumPeriod = MinimumPeriod;
249
	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
250
251
}

Gavin Wood's avatar
Gavin Wood committed
252
parameter_types! {
253
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
254
255
256
}

// TODO: substrate#2986 implement this properly
257
impl pallet_authorship::Config for Runtime {
258
	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
259
260
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
261
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
262
263
}

264
265
266
267
268
269
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

impl_opaque_keys! {
270
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
271
272
273
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
274
275
		pub para_validator: ParachainSessionKeyPlaceholder<Runtime>,
		pub para_assignment: AssignmentSessionKeyPlaceholder<Runtime>,
Gavin Wood's avatar
Gavin Wood committed
276
		pub authority_discovery: AuthorityDiscovery,
277
	}
278
279
}

thiolliere's avatar
thiolliere committed
280
281
282
283
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

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

297
impl pallet_session::historical::Config for Runtime {
298
299
	type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
300
301
}

302
303
304
305
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
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 = ();
334
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
335
336
}

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

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

Gavin Wood's avatar
Gavin Wood committed
368
369
370
type SlashCancelOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
371
	pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
372
373
>;

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

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

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

466
467
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
468
	pub const CouncilMaxProposals: u32 = 100;
469
	pub const CouncilMaxMembers: u32 = 100;
470
471
}

472
type CouncilCollective = pallet_collective::Instance1;
473
impl pallet_collective::Config<CouncilCollective> for Runtime {
474
475
476
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
477
	type MotionDuration = CouncilMotionDuration;
478
	type MaxProposals = CouncilMaxProposals;
479
	type MaxMembers = CouncilMaxMembers;
Wei Tang's avatar
Wei Tang committed
480
	type DefaultVote = pallet_collective::PrimeDefaultVote;
481
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
482
483
}

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

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

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

518
519
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
520
	pub const TechnicalMaxProposals: u32 = 100;
521
	pub const TechnicalMaxMembers: u32 = 100;
522
523
}

524
type TechnicalCollective = pallet_collective::Instance2;
525
impl pallet_collective::Config<TechnicalCollective> for Runtime {
526
527
528
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
529
	type MotionDuration = TechnicalMotionDuration;
530
	type MaxProposals = TechnicalMaxProposals;
531
	type MaxMembers = TechnicalMaxMembers;
Wei Tang's avatar
Wei Tang committed
532
	type DefaultVote = pallet_collective::PrimeDefaultVote;
533
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
534
535
}

536
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
537
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
538
539
540
541
542
	type AddOrigin = MoreThanHalfCouncil;
	type RemoveOrigin = MoreThanHalfCouncil;
	type SwapOrigin = MoreThanHalfCouncil;
	type ResetOrigin = MoreThanHalfCouncil;
	type PrimeOrigin = MoreThanHalfCouncil;
543
544
545
546
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
}

Gavin Wood's avatar
Gavin Wood committed
547
548
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
Gavin Wood's avatar
Gavin Wood committed
549
	pub const ProposalBondMinimum: Balance = 20 * DOLLARS;
550
	pub const SpendPeriod: BlockNumber = 6 * DAYS;
551
	pub const Burn: Permill = Permill::from_perthousand(2);
552
	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
553
554
555
556

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
	pub const TipReportDepositBase: Balance = 1 * DOLLARS;
557
558
559
560
561
562
563
	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
564
565
}

Gavin Wood's avatar
Gavin Wood committed
566
567
568
type ApproveOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
569
	pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
570
571
>;

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

impl pallet_bounties::Config for Runtime {
	type Event = Event;
590
591
592
593
594
	type BountyDepositBase = BountyDepositBase;
	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
	type BountyUpdatePeriod = BountyUpdatePeriod;
	type BountyCuratorDeposit = BountyCuratorDeposit;
	type BountyValueMinimum = BountyValueMinimum;
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
	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>;
610
}
611

612
parameter_types! {
613
	pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * BlockWeights::get().max_block;
614
615
}

616
impl pallet_offences::Config for Runtime {
617
	type Event = Event;
618
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
619
	type OnOffenceHandler = Staking;
620
	type WeightSoftLimit = OffencesWeightSoftLimit;
621
622
}

623
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
624

625
626
627
628
parameter_types! {
	pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _;
}

629
parameter_types! {
630
631
	pub StakingUnsignedPriority: TransactionPriority =
		Perbill::from_percent(90) * TransactionPriority::max_value();
632
633
634
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

635
impl pallet_im_online::Config for Runtime {
thiolliere's avatar
thiolliere committed
636
	type AuthorityId = ImOnlineId;
637
	type Event = Event;
638
	type ValidatorSet = Historical;
639
	type ReportUnresponsiveness = Offences;
640
	type SessionDuration = SessionDuration;
641
	type UnsignedPriority = ImOnlineUnsignedPriority;
642
	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
643
644
}

645
impl pallet_grandpa::Config for Runtime {
646
	type Event = Event;
647
648
649
650
651
652
653
654
655
656
657
658
	type Call = Call;

	type KeyOwnerProofSystem = Historical;

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

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

659
660
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
661
662

	type WeightInfo = ();
663
664
}

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

710
impl frame_system::offchain::SigningTypes for Runtime {
711
712
713
714
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

715
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where
716
717
718
719
720
721
	Call: From<C>,
{
	type OverarchingCall = Call;
	type Extrinsic = UncheckedExtrinsic;
}

Gavin Wood's avatar
Gavin Wood committed
722
parameter_types! {
723
	pub Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:";
724
725
}

726
impl claims::Config for Runtime {
727
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
728
	type VestingSchedule = Vesting;
729
	type Prefix = Prefix;
730
	type MoveClaimOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
731
	type WeightInfo = weights::runtime_common_claims::WeightInfo<Runtime>;
732
733
}

734
parameter_types! {
735
	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
Gavin Wood's avatar
Gavin Wood committed
736
737
738
	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
739
740
	pub const MaxSubAccounts: u32 = 100;
	pub const MaxAdditionalFields: u32 = 100;
741
	pub const MaxRegistrars: u32 = 20;
742
743
}

744
impl pallet_identity::Config for Runtime {
745
746
747
748
749
750
	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
751
752
	type MaxSubAccounts = MaxSubAccounts;
	type MaxAdditionalFields = MaxAdditionalFields;
753
	type MaxRegistrars = MaxRegistrars;
Gavin Wood's avatar
Gavin Wood committed
754
755
	type RegistrarOrigin = MoreThanHalfCouncil;
	type ForceOrigin = MoreThanHalfCouncil;
756
	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
757
758
}

759
impl pallet_utility::Config for Runtime {
760
761
	type Event = Event;
	type Call = Call;
762
	type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
763
764
}

Gavin Wood's avatar
Gavin Wood committed
765
parameter_types! {
766
767
	// 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
768
	// Additional storage item size of 32 bytes.
769
	pub const DepositFactor: Balance = deposit(0, 32);
Gavin Wood's avatar
Gavin Wood committed
770
771
772
	pub const MaxSignatories: u16 = 100;
}

773
impl pallet_multisig::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
774
775
776
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
777
778
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
Gavin Wood's avatar
Gavin Wood committed
779
	type MaxSignatories = MaxSignatories;
780
	type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
Gavin Wood's avatar
Gavin Wood committed
781
782
}

783
784
785
786
787
788
789
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;
}

790
impl pallet_recovery::Config for Runtime {
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
	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;
808
	pub const SocietyModuleId: ModuleId = ModuleId(*b"py/socie");
809
810
}