lib.rs 68.4 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
#[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},
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;
Kian Paimani's avatar
Kian Paimani committed
104
pub use pallet_election_provider_multi_phase::Call as EPMCall;
105
106
107

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

244
245
	type KeyOwnerProofSystem = Historical;

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

	type WeightInfo = ();
250
251
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Kian Paimani's avatar
Kian Paimani committed
352
use pallet_election_provider_multi_phase::WeightInfo;
353
parameter_types! {
354
355
	// phase durations. 1/4 of the last session for each.
	pub const SignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
356
	pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
357

358
359
360
361
362
363
364
	// 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
365
366
367
368
369
370
371
372
	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
	);
373
374

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

747
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
748

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

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

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

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

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

777
778
	type KeyOwnerProofSystem = Historical;

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

	type WeightInfo = ();
783
784
}

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