lib.rs 68.2 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 Kusama 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
	AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
30
	CoreState, GroupRotationInfo, Hash, Id as ParaId, Moment, Nonce, OccupiedCoreAssumption,
31
32
	PersistedValidationData, Signature, ValidationCode, ValidationCodeHash, ValidatorId,
	ValidatorIndex, InboundDownwardMessage, InboundHrmpMessage, SessionInfo,
33
};
34
use runtime_common::{
35
36
	claims, paras_registrar, xcm_sender, slots, auctions, crowdloan,
	SlowAdjustingFeeUpdate, CurrencyToVote, impls::DealWithFees,
37
38
	BlockHashCount, RocksDbWeight, BlockWeights, BlockLength,
	OffchainSolutionWeightLimit, OffchainSolutionLengthLimit, elections::fee_for_submit_call,
39
	ToAuthor,
40
};
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

use runtime_parachains::origin as parachains_origin;
use runtime_parachains::configuration as parachains_configuration;
use runtime_parachains::shared as parachains_shared;
use runtime_parachains::inclusion as parachains_inclusion;
use runtime_parachains::paras_inherent as parachains_paras_inherent;
use runtime_parachains::initializer as parachains_initializer;
use runtime_parachains::session_info as parachains_session_info;
use runtime_parachains::paras as parachains_paras;
use runtime_parachains::dmp as parachains_dmp;
use runtime_parachains::ump as parachains_ump;
use runtime_parachains::hrmp as parachains_hrmp;
use runtime_parachains::scheduler as parachains_scheduler;
use runtime_parachains::reward_points as parachains_reward_points;
use runtime_parachains::runtime_api_impl::v1 as parachains_runtime_api_impl;

57
58
use xcm::v0::{MultiLocation::{self, Null, X1}, NetworkId, BodyId, Xcm, Junction::Parachain};
use xcm::v0::MultiAsset::{self, AllConcreteFungible};
59
60
use xcm_builder::{
	AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter,
61
62
	ChildParachainAsNative, SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter,
	IsConcrete, FixedWeightBounds, TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
63
	IsChildSystemParachain, UsingComponents, BackingToPlurality, SignedToAccountId32,
64
65
};
use xcm_executor::XcmExecutor;
66
use sp_arithmetic::Perquintill;
67
use sp_runtime::{
Shawn Tabrizi's avatar
Shawn Tabrizi committed
68
	create_runtime_str, generic, impl_opaque_keys,
69
	ApplyExtrinsicResult, KeyTypeId, Percent, Permill, Perbill,
Gavin Wood's avatar
Gavin Wood committed
70
	transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority},
71
	traits::{
72
		BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, AccountIdLookup,
Gavin Wood's avatar
Gavin Wood committed
73
		Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
74
	},
Gav Wood's avatar
Gav Wood committed
75
};
76
77
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
78
79
use sp_version::RuntimeVersion;
use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives};
80
#[cfg(any(feature = "std", test))]
81
use sp_version::NativeVersion;
82
83
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
84
use frame_support::{
Shawn Tabrizi's avatar
Shawn Tabrizi committed
85
	parameter_types, construct_runtime, RuntimeDebug, PalletId,
86
	traits::{KeyOwnerProofSystem, LockIdentifier, Filter, InstanceFilter, All, MaxEncodedLen},
87
	weights::Weight,
Gavin Wood's avatar
Gavin Wood committed
88
};
89
90
use frame_system::{EnsureRoot, EnsureOneOf};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
91
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
92
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
93
use pallet_session::historical as session_historical;
94
use static_assertions::const_assert;
Andreas Doerr's avatar
Andreas Doerr committed
95
use beefy_primitives::crypto::AuthorityId as BeefyId;
96
use pallet_mmr_primitives as mmr;
97

Gav Wood's avatar
Gav Wood committed
98
#[cfg(feature = "std")]
99
pub use pallet_staking::StakerStatus;
100
#[cfg(any(feature = "std", test))]
101
pub use sp_runtime::BuildStorage;
102
103
pub use pallet_timestamp::Call as TimestampCall;
pub use pallet_balances::Call as BalancesCall;
104
105
106

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

109
110
111
// Weights used in the runtime.
mod weights;

112
113
114
#[cfg(test)]
mod tests;

115
116
117
118
// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

119
120
121
122
/// Runtime version (Kusama).
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("kusama"),
	impl_name: create_runtime_str!("parity-kusama"),
123
	authoring_version: 2,
124
	spec_version: 9080,
125
	impl_version: 0,
126
	#[cfg(not(feature = "disable-runtime-api"))]
127
	apis: RUNTIME_API_VERSIONS,
128
	#[cfg(feature = "disable-runtime-api")]
129
	apis: version::create_apis_vec![[]],
130
	transaction_version: 5,
131
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
132

133
134
135
136
137
138
139
/// 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
	};

140
141
142
143
144
145
146
147
148
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

149
/// Don't allow swaps until parathread story is more mature.
150
151
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
152
153
	fn filter(c: &Call) -> bool {
		!matches!(c,
154
			Call::Registrar(paras_registrar::Call::swap(..))
155
		)
156
157
158
	}
}

Gavin Wood's avatar
Gavin Wood committed
159
160
161
type MoreThanHalfCouncil = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
162
	pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
163
164
>;

165
parameter_types! {
166
	pub const Version: RuntimeVersion = VERSION;
167
	pub const SS58Prefix: u8 = 2;
168
169
}

170
impl frame_system::Config for Runtime {
171
	type BaseCallFilter = BaseFilter;
172
173
	type BlockWeights = BlockWeights;
	type BlockLength = BlockLength;
174
	type Origin = Origin;
175
	type Call = Call;
Gav Wood's avatar
Gav Wood committed
176
	type Index = Nonce;
177
178
179
180
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
181
	type Lookup = AccountIdLookup<AccountId, ()>;
182
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
Gav's avatar
Gav committed
183
	type Event = Event;
184
	type BlockHashCount = BlockHashCount;
185
	type DbWeight = RocksDbWeight;
186
	type Version = Version;
187
	type PalletInfo = PalletInfo;
188
	type AccountData = pallet_balances::AccountData<Balance>;
189
	type OnNewAccount = ();
190
	type OnKilledAccount = ();
191
	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
192
	type SS58Prefix = SS58Prefix;
193
	type OnSetCode = ();
194
195
}

196
parameter_types! {
197
198
	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
		BlockWeights::get().max_block;
199
200
201
	pub const MaxScheduledPerBlock: u32 = 50;
}

202
203
204
205
206
207
type ScheduleOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
	pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>
>;

208
impl pallet_scheduler::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
209
210
	type Event = Event;
	type Origin = Origin;
211
	type PalletsOrigin = OriginCaller;
Gavin Wood's avatar
Gavin Wood committed
212
	type Call = Call;
213
	type MaximumWeight = MaximumSchedulerWeight;
214
	type ScheduleOrigin = ScheduleOrigin;
215
	type MaxScheduledPerBlock = MaxScheduledPerBlock;
216
	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
Gavin Wood's avatar
Gavin Wood committed
217
218
}

219
parameter_types! {
220
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
221
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
222
223
	pub const ReportLongevity: u64 =
		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
224
225
}

226
impl pallet_babe::Config for Runtime {
227
228
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
229
230

	// session module is the trigger
231
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
232
233
234

	type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
235
		pallet_babe::AuthorityId,
236
237
238
239
	)>>::Proof;

	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
240
		pallet_babe::AuthorityId,
241
242
	)>>::IdentificationTuple;

243
244
	type KeyOwnerProofSystem = Historical;

245
	type HandleEquivocation =
246
		pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
247
248

	type WeightInfo = ();
249
250
}

Gavin Wood's avatar
Gavin Wood committed
251
parameter_types! {
252
	pub const IndexDeposit: Balance = 100 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
253
254
}

255
impl pallet_indices::Config for Runtime {
Gav Wood's avatar
Gav Wood committed
256
	type AccountIndex = AccountIndex;
257
258
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
259
	type Event = Event;
260
	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
Gav Wood's avatar
Gav Wood committed
261
262
}

Gavin Wood's avatar
Gavin Wood committed
263
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
264
	pub const ExistentialDeposit: Balance = 1 * CENTS;
265
	pub const MaxLocks: u32 = 50;
Gavin Wood's avatar
Gavin Wood committed
266
	pub const MaxReserves: u32 = 50;
Gavin Wood's avatar
Gavin Wood committed
267
268
}

269
impl pallet_balances::Config for Runtime {
Gav's avatar
Gav committed
270
	type Balance = Balance;
271
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
272
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
273
	type ExistentialDeposit = ExistentialDeposit;
274
	type AccountStore = System;
275
	type MaxLocks = MaxLocks;
Gavin Wood's avatar
Gavin Wood committed
276
277
278
	type MaxReserves = MaxReserves;
	type ReserveIdentifier = [u8; 8];
	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
279
280
281
282
283
284
}

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

285
impl pallet_transaction_payment::Config for Runtime {
Albrecht's avatar
Albrecht committed
286
	type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees<Self>>;
Gavin Wood's avatar
Gavin Wood committed
287
	type TransactionByteFee = TransactionByteFee;
288
	type WeightToFee = WeightToFee;
289
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
Gav's avatar
Gav committed
290
291
}

292
parameter_types! {
293
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
294
}
295
impl pallet_timestamp::Config for Runtime {
296
	type Moment = u64;
297
	type OnTimestampSet = Babe;
298
	type MinimumPeriod = MinimumPeriod;
299
	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
300
301
}

Gavin Wood's avatar
Gavin Wood committed
302
parameter_types! {
303
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
304
305
}

306
impl pallet_authorship::Config for Runtime {
307
	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
308
309
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
310
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
311
312
}

313
314
315
316
317
318
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

impl_opaque_keys! {
319
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
320
321
322
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
323
324
		pub para_validator: ParasInitializer,
		pub para_assignment: ParasSessionInfo,
Gavin Wood's avatar
Gavin Wood committed
325
		pub authority_discovery: AuthorityDiscovery,
326
	}
327
328
}

thiolliere's avatar
thiolliere committed
329
330
331
332
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

333
impl pallet_session::Config for Runtime {
Gav's avatar
Gav committed
334
	type Event = Event;
335
	type ValidatorId = AccountId;
336
	type ValidatorIdOf = pallet_staking::StashOf<Self>;
Gavin Wood's avatar
Gavin Wood committed
337
	type ShouldEndSession = Babe;
338
	type NextSessionRotation = Babe;
339
	type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
Gavin Wood's avatar
Gavin Wood committed
340
341
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
thiolliere's avatar
thiolliere committed
342
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
343
	type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
344
345
}

346
impl pallet_session::historical::Config for Runtime {
347
348
	type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
349
350
}

351
parameter_types! {
352
353
	// phase durations. 1/4 of the last session for each.
	pub const SignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
354
	pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
355

356
357
358
359
360
361
362
363
364
365
366
367
368
369
	// signed config
	pub const SignedMaxSubmissions: u32 = 16;
	pub const SignedDepositBase: Balance = deposit(1, 0);
	// A typical solution occupies within an order of magnitude of 50kb.
	// This formula is currently adjusted such that a typical solution will spend an amount equal
	// to the base deposit for every 50 kb.
	pub const SignedDepositByte: Balance = deposit(1, 0) / (50 * 1024);
	pub SignedRewardBase: Balance = fee_for_submit_call::<
		Runtime,
		crate::constants::fee::WeightToFee,
		crate::weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>,
	>(Perbill::from_perthousand(1500));

	// fallback: emergency phase.
370
	pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy =
371
		pallet_election_provider_multi_phase::FallbackStrategy::Nothing;
372
	pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(5u32, 10_000);
373
374
375

	// miner configs
	pub const MinerMaxIterations: u32 = 10;
376
	pub OffchainRepeat: BlockNumber = 5;
377
378
}

379
380
sp_npos_elections::generate_solution_type!(
	#[compact]
Kian Paimani's avatar
Kian Paimani committed
381
	pub struct NposCompactSolution24::<
382
383
384
		VoterIndex = u32,
		TargetIndex = u16,
		Accuracy = sp_runtime::PerU16,
Kian Paimani's avatar
Kian Paimani committed
385
	>(24)
386
387
);

388
389
390
391
impl pallet_election_provider_multi_phase::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
	type UnsignedPhase = UnsignedPhase;
392
393
394
395
396
397
398
399
	type SignedMaxSubmissions = SignedMaxSubmissions;
	type SignedRewardBase = SignedRewardBase;
	type SignedDepositBase = SignedDepositBase;
	type SignedDepositByte = SignedDepositByte;
	type SignedDepositWeight = ();
	type SignedMaxWeight = Self::MinerMaxWeight;
	type SlashHandler = (); // burn slashes
	type RewardHandler = (); // nothing to do upon rewards
400
	type SignedPhase = SignedPhase;
401
	type SolutionImprovementThreshold = SolutionImprovementThreshold;
402
	type MinerMaxIterations = MinerMaxIterations;
403
	type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
404
	type MinerMaxLength = OffchainSolutionLengthLimit;
405
	type OffchainRepeat = OffchainRepeat;
406
	type MinerTxPriority = NposSolutionPriority;
407
	type DataProvider = Staking;
Kian Paimani's avatar
Kian Paimani committed
408
	type CompactSolution = NposCompactSolution24;
409
	type OnChainAccuracy = Perbill;
410
411
	type Fallback = Fallback;
	type BenchmarkingConfig = ();
412
413
414
415
416
	type ForceOrigin = EnsureOneOf<
		AccountId,
		EnsureRoot<AccountId>,
		pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
	>;
417
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
418
419
}

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
fn era_payout(
	total_staked: Balance,
	non_gilt_issuance: Balance,
	max_annual_inflation: Perquintill,
	period_fraction: Perquintill,
	auctioned_slots: u64,
) -> (Balance, Balance) {
	use sp_arithmetic::traits::Saturating;
	use pallet_staking_reward_fn::compute_inflation;

	let min_annual_inflation = Perquintill::from_rational(25u64, 1000u64);
	let delta_annual_inflation = max_annual_inflation.saturating_sub(min_annual_inflation);

	// 30% reserved for up to 60 slots.
	let auction_proportion = Perquintill::from_rational(auctioned_slots.min(60), 200u64);

	// Therefore the ideal amount at stake (as a percentage of total issuance) is 75% less the amount that we expect
	// to be taken up with auctions.
	let ideal_stake = Perquintill::from_percent(75)
		.saturating_sub(auction_proportion);

	let stake = Perquintill::from_rational(total_staked, non_gilt_issuance);
	let falloff = Perquintill::from_percent(5);
	let adjustment = compute_inflation(stake, ideal_stake, falloff);
	let staking_inflation = min_annual_inflation.saturating_add(delta_annual_inflation * adjustment);

	let max_payout = period_fraction * max_annual_inflation * non_gilt_issuance;
	let staking_payout = (period_fraction * staking_inflation) * non_gilt_issuance;
	let rest = max_payout.saturating_sub(staking_payout);

	let other_issuance = non_gilt_issuance.saturating_sub(total_staked);
	if total_staked > other_issuance {
		let _cap_rest = Perquintill::from_rational(other_issuance, total_staked) * staking_payout;
		// We don't do anything with this, but if we wanted to, we could introduce a cap on the treasury amount
		// with: `rest = rest.min(cap_rest);`
	}
	(staking_payout, rest)
}

pub struct EraPayout;
impl pallet_staking::EraPayout<Balance> for EraPayout {
	fn era_payout(
		total_staked: Balance,
		_total_issuance: Balance,
		era_duration_millis: u64,
	) -> (Balance, Balance) {
466
467
468
		// TODO: #3011 Update with proper auctioned slots tracking.
		// This should be fine for the first year of parachains.
		let auctioned_slots: u64 = auctions::Pallet::<Runtime>::auction_counter().into();
469
470
471
472
473
474
475
476
		const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10);
		const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;

		era_payout(
			total_staked,
			Gilt::issuance().non_gilt,
			MAX_ANNUAL_INFLATION,
			Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR),
477
			auctioned_slots,
478
479
		)
	}
thiolliere's avatar
thiolliere committed
480
481
}

482
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
483
	// Six sessions in an era (6 hours).
484
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
485
	// 28 eras for unbonding (7 days).
486
	pub const BondingDuration: pallet_staking::EraIndex = 28;
487
	// 27 eras in which slashes can be cancelled (slightly less than 7 days).
488
	pub const SlashDeferDuration: pallet_staking::EraIndex = 27;
489
	pub const MaxNominatorRewardedPerValidator: u32 = 256;
490
}
491

Gavin Wood's avatar
Gavin Wood committed
492
493
494
type SlashCancelOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
495
	pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
496
497
>;

498
impl pallet_staking::Config for Runtime {
Kian Paimani's avatar
Kian Paimani committed
499
	const MAX_NOMINATIONS: u32 = <NposCompactSolution24 as sp_npos_elections::CompactSolution>::LIMIT as u32;
Gavin Wood's avatar
Gavin Wood committed
500
	type Currency = Balances;
501
	type UnixTime = Timestamp;
502
	type CurrencyToVote = CurrencyToVote;
503
	type ElectionProvider = ElectionProviderMultiPhase;
504
505
506
507
	type GenesisElectionProvider =
		frame_election_provider_support::onchain::OnChainSequentialPhragmen<
			pallet_election_provider_multi_phase::OnChainConfig<Self>
		>;
Gavin Wood's avatar
Gavin Wood committed
508
	type RewardRemainder = Treasury;
Gav's avatar
Gav committed
509
	type Event = Event;
510
	type Slash = Treasury;
511
	type Reward = ();
512
513
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
514
	type SlashDeferDuration = SlashDeferDuration;
Gavin Wood's avatar
Gavin Wood committed
515
516
	// A majority of the council or root can cancel the slash.
	type SlashCancelOrigin = SlashCancelOrigin;
517
	type SessionInterface = Self;
518
	type EraPayout = EraPayout;
519
	type NextNewSession = Session;
520
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
521
	type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
522
523
}

524
parameter_types! {
525
526
	pub const LaunchPeriod: BlockNumber = 7 * DAYS;
	pub const VotingPeriod: BlockNumber = 7 * DAYS;
527
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
528
	pub const MinimumDeposit: Balance = 100 * CENTS;
529
530
	pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
531
	// One cent: $10,000 / MB
Gavin Wood's avatar
Gavin Wood committed
532
	pub const PreimageByteDeposit: Balance = 10 * MILLICENTS;
533
	pub const InstantAllowed: bool = true;
534
	pub const MaxVotes: u32 = 100;
535
	pub const MaxProposals: u32 = 100;
536
537
}

538
impl pallet_democracy::Config for Runtime {
539
540
	type Proposal = Call;
	type Event = Event;
541
	type Currency = Balances;
542
543
544
545
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
	type MinimumDeposit = MinimumDeposit;
546
	/// A straight majority of the council can decide what their next motion is.
547
	type ExternalOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
548
	/// A majority can have the next scheduled referendum be a straight majority-carries vote.
549
	type ExternalMajorityOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
550
551
	/// A unanimous council can have the next scheduled referendum be a straight default-carries
	/// (NTB) vote.
552
	type ExternalDefaultOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>;
553
554
	/// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote
	/// be tabled immediately and with a shorter voting/enactment period.
555
556
	type FastTrackOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>;
	type InstantOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>;
557
558
	type InstantAllowed = InstantAllowed;
	type FastTrackVotingPeriod = FastTrackVotingPeriod;
559
	// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
560
561
562
563
564
	type CancellationOrigin = EnsureOneOf<
		AccountId,
		EnsureRoot<AccountId>,
		pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
	>;
565
	type BlacklistOrigin = EnsureRoot<AccountId>;
566
567
568
569
570
571
572
	// 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>,
	>;
573
574
	// 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.
575
	type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
576
	type CooloffPeriod = CooloffPeriod;
Gavin Wood's avatar
Gavin Wood committed
577
	type PreimageByteDeposit = PreimageByteDeposit;
578
	type OperationalPreimageOrigin = pallet_collective::EnsureMember<AccountId, CouncilCollective>;
Gavin Wood's avatar
Gavin Wood committed
579
	type Slash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
580
	type Scheduler = Scheduler;
581
	type PalletsOrigin = OriginCaller;
582
	type MaxVotes = MaxVotes;
583
584
	type WeightInfo = weights::pallet_democracy::WeightInfo<Runtime>;
	type MaxProposals = MaxProposals;
585
}
586

587
588
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
589
	pub const CouncilMaxProposals: u32 = 100;
590
	pub const CouncilMaxMembers: u32 = 100;
591
592
}

593
type CouncilCollective = pallet_collective::Instance1;
594
impl pallet_collective::Config<CouncilCollective> for Runtime {
595
596
597
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
598
	type MotionDuration = CouncilMotionDuration;
599
	type MaxProposals = CouncilMaxProposals;
600
	type MaxMembers = CouncilMaxMembers;
Wei Tang's avatar
Wei Tang committed
601
	type DefaultVote = pallet_collective::PrimeDefaultVote;
602
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
603
604
}

Gavin Wood's avatar
Gavin Wood committed
605
parameter_types! {
606
	pub const CandidacyBond: Balance = 100 * CENTS;
Kian Paimani's avatar
Kian Paimani committed
607
608
609
610
611
	// 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
612
	pub const TermDuration: BlockNumber = 24 * HOURS;
613
614
	pub const DesiredMembers: u32 = 19;
	pub const DesiredRunnersUp: u32 = 19;
615
	pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect";
616
}
Kian Paimani's avatar
Kian Paimani committed
617

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

621
impl pallet_elections_phragmen::Config for Runtime {
622
	type Event = Event;
623
624
	type Currency = Balances;
	type ChangeMembers = Council;
625
	type InitializeMembers = Council;
626
	type CurrencyToVote = frame_support::traits::U128CurrencyToVote;
Gavin Wood's avatar
Gavin Wood committed
627
	type CandidacyBond = CandidacyBond;
Kian Paimani's avatar
Kian Paimani committed
628
629
	type VotingBondBase = VotingBondBase;
	type VotingBondFactor = VotingBondFactor;
630
631
	type LoserCandidate = Treasury;
	type KickedMember = Treasury;
Gavin Wood's avatar
Gavin Wood committed
632
633
634
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
	type TermDuration = TermDuration;
635
	type PalletId = PhragmenElectionPalletId;
636
	type WeightInfo = weights::pallet_elections_phragmen::WeightInfo<Runtime>;
637
638
}

639
640
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
641
	pub const TechnicalMaxProposals: u32 = 100;
642
	pub const TechnicalMaxMembers: u32 = 100;
643
644
}

645
type TechnicalCollective = pallet_collective::Instance2;
646
impl pallet_collective::Config<TechnicalCollective> for Runtime {
647
648
649
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
650
	type MotionDuration = TechnicalMotionDuration;
651
	type MaxProposals = TechnicalMaxProposals;
652
	type MaxMembers = TechnicalMaxMembers;
Wei Tang's avatar
Wei Tang committed
653
	type DefaultVote = pallet_collective::PrimeDefaultVote;
654
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
655
656
}

657
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
658
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
659
660
661
662
663
	type AddOrigin = MoreThanHalfCouncil;
	type RemoveOrigin = MoreThanHalfCouncil;
	type SwapOrigin = MoreThanHalfCouncil;
	type ResetOrigin = MoreThanHalfCouncil;
	type PrimeOrigin = MoreThanHalfCouncil;
664
665
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
666
	type MaxMembers = TechnicalMaxMembers;
Kian Paimani's avatar
Kian Paimani committed
667
	type WeightInfo = weights::pallet_membership::WeightInfo<Runtime>;
668
669
}

Gavin Wood's avatar
Gavin Wood committed
670
671
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
672
	pub const ProposalBondMinimum: Balance = 2000 * CENTS;
673
	pub const SpendPeriod: BlockNumber = 6 * DAYS;
674
	pub const Burn: Permill = Permill::from_perthousand(2);
Shawn Tabrizi's avatar
Shawn Tabrizi committed
675
	pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
676
677
678

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
679
	pub const TipReportDepositBase: Balance = 100 * CENTS;
680
	pub const DataDepositPerByte: Balance = 1 * CENTS;
681
	pub const BountyDepositBase: Balance = 100 * CENTS;
682
683
684
685
	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);
686
	pub const BountyValueMinimum: Balance = 200 * CENTS;
687
	pub const MaxApprovals: u32 = 100;
Gavin Wood's avatar
Gavin Wood committed
688
689
}

Gavin Wood's avatar
Gavin Wood committed
690
691
692
type ApproveOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
693
	pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
694
695
>;

696
impl pallet_treasury::Config for Runtime {
Shawn Tabrizi's avatar
Shawn Tabrizi committed
697
	type PalletId = TreasuryPalletId;
Gavin Wood's avatar
Gavin Wood committed
698
	type Currency = Balances;
Gavin Wood's avatar
Gavin Wood committed
699
700
	type ApproveOrigin = ApproveOrigin;
	type RejectOrigin = MoreThanHalfCouncil;
701
	type Event = Event;
702
	type OnSlash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
703
704
705
706
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
707
	type BurnDestination = Society;
708
	type MaxApprovals = MaxApprovals;
709
	type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
710
	type SpendFunds = Bounties;
711
712
713
}

impl pallet_bounties::Config for Runtime {
714
715
716
717
718
	type BountyDepositBase = BountyDepositBase;
	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
	type BountyUpdatePeriod = BountyUpdatePeriod;
	type BountyCuratorDeposit = BountyCuratorDeposit;
	type BountyValueMinimum = BountyValueMinimum;
719
	type DataDepositPerByte = DataDepositPerByte;
720
	type Event = Event;
721
722
723
724
725
726
	type MaximumReasonLength = MaximumReasonLength;
	type WeightInfo = weights::pallet_bounties::WeightInfo<Runtime>;
}

impl pallet_tips::Config for Runtime {
	type MaximumReasonLength = MaximumReasonLength;
727
	type DataDepositPerByte = DataDepositPerByte;
728
	type Tippers = PhragmenElection;
729
730
731
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
732
	type Event = Event;
733
	type WeightInfo = weights::pallet_tips::WeightInfo<Runtime>;
734
}
735

736
impl pallet_offences::Config for Runtime {
737
	type Event = Event;
738
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
739
740
741
	type OnOffenceHandler = Staking;
}

742
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
743

744
parameter_types! {
745
	pub NposSolutionPriority: TransactionPriority =
746
		Perbill::from_percent(90) * TransactionPriority::max_value();
747
748
749
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

750
impl pallet_im_online::Config for Runtime {
thiolliere's avatar
thiolliere committed
751
	type AuthorityId = ImOnlineId;
752
	type Event = Event;
753
	type ValidatorSet = Historical;
754
	type NextSessionRotation = Babe;
755
	type ReportUnresponsiveness = Offences;
756
	type UnsignedPriority = ImOnlineUnsignedPriority;
757
	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
758
759
}

760
impl pallet_grandpa::Config for Runtime {
761
	type Event = Event;
762
763
764
765
766
767
768
769
770
771
	type Call = Call;

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

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

772
773
	type KeyOwnerProofSystem = Historical;

774
775
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
776
777

	type WeightInfo = ();
778
779
}

780
781
/// Submits transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
782
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
783
784
	Call: From<LocalCall>,
{
785
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
786
787
788
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
789
		nonce: <Runtime as frame_system::Config>::Index,
790
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
791
		use sp_runtime::traits::StaticLookup;
792
		// take the biggest period possible.
793
794
795
796
797
798
799