lib.rs 68.5 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, MaxEncodedLen};
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::{
Kian Paimani's avatar
Kian Paimani committed
68
69
	create_runtime_str, generic, impl_opaque_keys, ApplyExtrinsicResult, KeyTypeId, Percent,
	Permill, Perbill, FixedPointNumber,
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
use sp_version::RuntimeVersion;
use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives};
78
#[cfg(any(feature = "std", test))]
79
use sp_version::NativeVersion;
80
81
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
82
use frame_support::{
Shawn Tabrizi's avatar
Shawn Tabrizi committed
83
	parameter_types, construct_runtime, RuntimeDebug, PalletId,
84
	traits::{KeyOwnerProofSystem, LockIdentifier, Filter, InstanceFilter, All},
85
	weights::Weight,
Gavin Wood's avatar
Gavin Wood committed
86
};
87
88
use frame_system::{EnsureRoot, EnsureOneOf};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
89
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
90
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
91
use pallet_session::historical as session_historical;
92
use static_assertions::const_assert;
Andreas Doerr's avatar
Andreas Doerr committed
93
use beefy_primitives::crypto::AuthorityId as BeefyId;
94
use pallet_mmr_primitives as mmr;
95

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

242
243
	type KeyOwnerProofSystem = Historical;

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

	type WeightInfo = ();
248
249
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Kian Paimani's avatar
Kian Paimani committed
350
use pallet_election_provider_multi_phase::WeightInfo;
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
	// 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);
Kian Paimani's avatar
Kian Paimani committed
363
364
365
366
367
368
369
370
	pub SignedRewardBase: Balance = fee_for_submit_call::<Runtime>(
		// give 20% threshold.
		sp_runtime::FixedU128::saturating_from_rational(12, 10),
		// maximum weight possible.
		weights::pallet_election_provider_multi_phase::WeightInfo::<Runtime>::submit(SignedMaxSubmissions::get()),
		// assume a solution of 100kb length.
		100 * 1024
	);
371
372

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

	// miner configs
	pub const MinerMaxIterations: u32 = 10;
379
	pub OffchainRepeat: BlockNumber = 5;
380
381
}

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

391
392
393
394
impl pallet_election_provider_multi_phase::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
	type UnsignedPhase = UnsignedPhase;
395
396
397
398
399
400
401
402
	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
403
	type SignedPhase = SignedPhase;
404
	type SolutionImprovementThreshold = SolutionImprovementThreshold;
405
	type MinerMaxIterations = MinerMaxIterations;
406
	type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
407
	type MinerMaxLength = OffchainSolutionLengthLimit;
408
	type OffchainRepeat = OffchainRepeat;
409
	type MinerTxPriority = NposSolutionPriority;
410
	type DataProvider = Staking;
Kian Paimani's avatar
Kian Paimani committed
411
	type CompactSolution = NposCompactSolution24;
412
	type OnChainAccuracy = Perbill;
413
414
	type Fallback = Fallback;
	type BenchmarkingConfig = ();
415
416
417
418
419
	type ForceOrigin = EnsureOneOf<
		AccountId,
		EnsureRoot<AccountId>,
		pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
	>;
420
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
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
466
467
468
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) {
469
470
471
		// 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();
472
473
474
475
476
477
478
479
		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),
480
			auctioned_slots,
481
482
		)
	}
thiolliere's avatar
thiolliere committed
483
484
}

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

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

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

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

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

590
591
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
592
	pub const CouncilMaxProposals: u32 = 100;
593
	pub const CouncilMaxMembers: u32 = 100;
594
595
}

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

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

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

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

642
643
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
644
	pub const TechnicalMaxProposals: u32 = 100;
645
	pub const TechnicalMaxMembers: u32 = 100;
646
647
}

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

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

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

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

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

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

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

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

739
impl pallet_offences::Config for Runtime {
740
	type Event = Event;
741
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
742
743
744
	type OnOffenceHandler = Staking;
}

745
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
746

747
parameter_types! {
748
	pub NposSolutionPriority: TransactionPriority =
749
		Perbill::from_percent(90) * TransactionPriority::max_value();
750
751
752
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

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

763
impl pallet_grandpa::Config for Runtime {
764
	type Event = Event;
765
766
767
768
769
770
771
772
773
774
	type Call = Call;

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

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

775
776
	type KeyOwnerProofSystem = Historical;

777
778
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
779
780

	type WeightInfo = ();
781
782
}

783
784
/// Submits transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
785
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
786
787
	Call: From<LocalCall>,
{
788
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
789
790
791
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
792
		nonce: <Runtime as frame_system::Config>::Index,
793
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
Shawn Tabrizi's avatar