lib.rs 68.6 KB
Newer Older
Shawn Tabrizi's avatar
Shawn Tabrizi committed
1
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
Gav's avatar
Gav committed
2
3
4
5
6
7
8
9
10
11
12
13
14
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
15
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
Gav's avatar
Gav committed
16

17
//! The Polkadot runtime. This can be compiled with `#[no_std]`, ready for Wasm.
Gav's avatar
Gav committed
18
19

#![cfg_attr(not(feature = "std"), no_std)]
20
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
21
#![recursion_limit = "256"]
Gav Wood's avatar
Gav Wood committed
22

Albrecht's avatar
Albrecht committed
23
use pallet_transaction_payment::CurrencyAdapter;
24
use sp_std::prelude::*;
Sergey Pepyakin's avatar
Sergey Pepyakin committed
25
use sp_std::collections::btree_map::BTreeMap;
26
use sp_core::u32_trait::{_1, _2, _3, _5};
27
use parity_scale_codec::{Encode, Decode};
28
use primitives::v1::{
29
	AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
30
	CoreState, GroupRotationInfo, Hash, Id as ParaId, Moment, Nonce, OccupiedCoreAssumption,
31
	PersistedValidationData, Signature, ValidationCode, ValidatorId, ValidatorIndex,
32
	InboundDownwardMessage, InboundHrmpMessage, SessionInfo,
33
};
34
use runtime_common::{
35
36
	claims, SlowAdjustingFeeUpdate, CurrencyToVote, paras_registrar, xcm_sender, slots, impls::DealWithFees,
	BlockHashCount, RocksDbWeight, BlockWeights, BlockLength, OffchainSolutionWeightLimit, OffchainSolutionLengthLimit,
37
	ToAuthor,
38
};
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

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;

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

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

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

106
107
108
// Weights used in the runtime.
mod weights;

109
110
111
#[cfg(test)]
mod tests;

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

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

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

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

146
/// Avoid processing transactions from slots and parachain registrar except by root.
147
148
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
149
150
151
152
153
	fn filter(c: &Call) -> bool {
		!matches!(c,
			Call::Registrar(..) |
			Call::Slots(..)
		)
154
155
156
	}
}

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

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

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

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

200
impl pallet_scheduler::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
201
202
	type Event = Event;
	type Origin = Origin;
203
	type PalletsOrigin = OriginCaller;
Gavin Wood's avatar
Gavin Wood committed
204
	type Call = Call;
205
	type MaximumWeight = MaximumSchedulerWeight;
206
	type ScheduleOrigin = EnsureRoot<AccountId>;
207
	type MaxScheduledPerBlock = MaxScheduledPerBlock;
208
	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
Gavin Wood's avatar
Gavin Wood committed
209
210
}

211
parameter_types! {
212
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
213
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
214
215
	pub const ReportLongevity: u64 =
		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
216
217
}

218
impl pallet_babe::Config for Runtime {
219
220
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
221
222

	// session module is the trigger
223
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
224
225
226

	type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
227
		pallet_babe::AuthorityId,
228
229
230
231
	)>>::Proof;

	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
232
		pallet_babe::AuthorityId,
233
234
	)>>::IdentificationTuple;

235
236
	type KeyOwnerProofSystem = Historical;

237
	type HandleEquivocation =
238
		pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
239
240

	type WeightInfo = ();
241
242
}

Gavin Wood's avatar
Gavin Wood committed
243
parameter_types! {
244
	pub const IndexDeposit: Balance = 100 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
245
246
}

247
impl pallet_indices::Config for Runtime {
Gav Wood's avatar
Gav Wood committed
248
	type AccountIndex = AccountIndex;
249
250
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
251
	type Event = Event;
252
	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
Gav Wood's avatar
Gav Wood committed
253
254
}

Gavin Wood's avatar
Gavin Wood committed
255
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
256
	pub const ExistentialDeposit: Balance = 1 * CENTS;
257
	pub const MaxLocks: u32 = 50;
Gavin Wood's avatar
Gavin Wood committed
258
259
}

260
impl pallet_balances::Config for Runtime {
Gav's avatar
Gav committed
261
	type Balance = Balance;
262
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
263
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
264
	type ExistentialDeposit = ExistentialDeposit;
265
	type AccountStore = System;
266
	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
267
	type MaxLocks = MaxLocks;
268
269
270
271
272
273
}

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

274
impl pallet_transaction_payment::Config for Runtime {
Albrecht's avatar
Albrecht committed
275
	type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees<Self>>;
Gavin Wood's avatar
Gavin Wood committed
276
	type TransactionByteFee = TransactionByteFee;
277
	type WeightToFee = WeightToFee;
278
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
Gav's avatar
Gav committed
279
280
}

281
parameter_types! {
282
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
283
}
284
impl pallet_timestamp::Config for Runtime {
285
	type Moment = u64;
286
	type OnTimestampSet = Babe;
287
	type MinimumPeriod = MinimumPeriod;
288
	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
289
290
}

Gavin Wood's avatar
Gavin Wood committed
291
parameter_types! {
292
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
293
294
}

295
impl pallet_authorship::Config for Runtime {
296
	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
297
298
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
299
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
300
301
}

302
303
304
305
306
307
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

impl_opaque_keys! {
308
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
309
310
311
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
312
313
		pub para_validator: ParasInitializer,
		pub para_assignment: ParasSessionInfo,
Gavin Wood's avatar
Gavin Wood committed
314
		pub authority_discovery: AuthorityDiscovery,
315
	}
316
317
}

thiolliere's avatar
thiolliere committed
318
319
320
321
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

322
impl pallet_session::Config for Runtime {
Gav's avatar
Gav committed
323
	type Event = Event;
324
	type ValidatorId = AccountId;
325
	type ValidatorIdOf = pallet_staking::StashOf<Self>;
Gavin Wood's avatar
Gavin Wood committed
326
	type ShouldEndSession = Babe;
327
	type NextSessionRotation = Babe;
328
	type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
Gavin Wood's avatar
Gavin Wood committed
329
330
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
thiolliere's avatar
thiolliere committed
331
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
332
	type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
333
334
}

335
impl pallet_session::historical::Config for Runtime {
336
337
	type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
338
339
}

340
341
342
parameter_types! {
	// no signed phase for now, just unsigned.
	pub const SignedPhase: u32 = 0;
343
	pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
344

345
	// fallback: run election on-chain.
346
	pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy =
347
348
		pallet_election_provider_multi_phase::FallbackStrategy::OnChain;
	pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(5u32, 10_000);
349
350
351

	// miner configs
	pub const MinerMaxIterations: u32 = 10;
352
	pub OffchainRepeat: BlockNumber = 5;
353
354
}

355
356
sp_npos_elections::generate_solution_type!(
	#[compact]
Kian Paimani's avatar
Kian Paimani committed
357
	pub struct NposCompactSolution24::<
358
359
360
		VoterIndex = u32,
		TargetIndex = u16,
		Accuracy = sp_runtime::PerU16,
Kian Paimani's avatar
Kian Paimani committed
361
	>(24)
362
363
);

364
365
366
367
impl pallet_election_provider_multi_phase::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
	type UnsignedPhase = UnsignedPhase;
368
	type SignedPhase = SignedPhase;
369
	type SolutionImprovementThreshold = SolutionImprovementThreshold;
370
	type MinerMaxIterations = MinerMaxIterations;
371
	type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
372
	type MinerMaxLength = OffchainSolutionLengthLimit;
373
	type OffchainRepeat = OffchainRepeat;
374
	type MinerTxPriority = NposSolutionPriority;
375
	type DataProvider = Staking;
Kian Paimani's avatar
Kian Paimani committed
376
	type CompactSolution = NposCompactSolution24;
377
	type OnChainAccuracy = Perbill;
378
379
	type Fallback = Fallback;
	type BenchmarkingConfig = ();
380
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
381
382
}

383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
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) {
		// TODO: #2999 Update with Auctions logic when auctions pallet added.
		const AUCTIONED_SLOTS: u64 = 0;
		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),
			AUCTIONED_SLOTS,
		)
	}
thiolliere's avatar
thiolliere committed
442
443
}

444
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
445
	// Six sessions in an era (6 hours).
446
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
447
	// 28 eras for unbonding (7 days).
448
	pub const BondingDuration: pallet_staking::EraIndex = 28;
449
	// 27 eras in which slashes can be cancelled (slightly less than 7 days).
450
	pub const SlashDeferDuration: pallet_staking::EraIndex = 27;
451
	pub const MaxNominatorRewardedPerValidator: u32 = 256;
452
}
453

Gavin Wood's avatar
Gavin Wood committed
454
455
456
type SlashCancelOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
457
	pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
458
459
>;

460
impl pallet_staking::Config for Runtime {
Kian Paimani's avatar
Kian Paimani committed
461
	const MAX_NOMINATIONS: u32 = <NposCompactSolution24 as sp_npos_elections::CompactSolution>::LIMIT as u32;
Gavin Wood's avatar
Gavin Wood committed
462
	type Currency = Balances;
463
	type UnixTime = Timestamp;
464
	type CurrencyToVote = CurrencyToVote;
465
	type ElectionProvider = ElectionProviderMultiPhase;
Gavin Wood's avatar
Gavin Wood committed
466
	type RewardRemainder = Treasury;
Gav's avatar
Gav committed
467
	type Event = Event;
468
	type Slash = Treasury;
469
	type Reward = ();
470
471
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
472
	type SlashDeferDuration = SlashDeferDuration;
Gavin Wood's avatar
Gavin Wood committed
473
474
	// A majority of the council or root can cancel the slash.
	type SlashCancelOrigin = SlashCancelOrigin;
475
	type SessionInterface = Self;
476
	type EraPayout = EraPayout;
477
	type NextNewSession = Session;
478
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
479
	type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
480
481
}

482
parameter_types! {
483
484
	pub const LaunchPeriod: BlockNumber = 7 * DAYS;
	pub const VotingPeriod: BlockNumber = 7 * DAYS;
485
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
486
	pub const MinimumDeposit: Balance = 100 * CENTS;
487
488
	pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
489
	// One cent: $10,000 / MB
Gavin Wood's avatar
Gavin Wood committed
490
	pub const PreimageByteDeposit: Balance = 10 * MILLICENTS;
491
	pub const InstantAllowed: bool = true;
492
	pub const MaxVotes: u32 = 100;
493
	pub const MaxProposals: u32 = 100;
494
495
}

496
impl pallet_democracy::Config for Runtime {
497
498
	type Proposal = Call;
	type Event = Event;
499
	type Currency = Balances;
500
501
502
503
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
	type MinimumDeposit = MinimumDeposit;
504
	/// A straight majority of the council can decide what their next motion is.
505
	type ExternalOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
506
	/// A majority can have the next scheduled referendum be a straight majority-carries vote.
507
	type ExternalMajorityOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
508
509
	/// A unanimous council can have the next scheduled referendum be a straight default-carries
	/// (NTB) vote.
510
	type ExternalDefaultOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>;
511
512
	/// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote
	/// be tabled immediately and with a shorter voting/enactment period.
513
514
	type FastTrackOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>;
	type InstantOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>;
515
516
	type InstantAllowed = InstantAllowed;
	type FastTrackVotingPeriod = FastTrackVotingPeriod;
517
	// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
518
519
520
521
522
	type CancellationOrigin = EnsureOneOf<
		AccountId,
		EnsureRoot<AccountId>,
		pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
	>;
523
	type BlacklistOrigin = EnsureRoot<AccountId>;
524
525
526
527
528
529
530
	// 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>,
	>;
531
532
	// 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.
533
	type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
534
	type CooloffPeriod = CooloffPeriod;
Gavin Wood's avatar
Gavin Wood committed
535
	type PreimageByteDeposit = PreimageByteDeposit;
536
	type OperationalPreimageOrigin = pallet_collective::EnsureMember<AccountId, CouncilCollective>;
Gavin Wood's avatar
Gavin Wood committed
537
	type Slash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
538
	type Scheduler = Scheduler;
539
	type PalletsOrigin = OriginCaller;
540
	type MaxVotes = MaxVotes;
541
542
	type WeightInfo = weights::pallet_democracy::WeightInfo<Runtime>;
	type MaxProposals = MaxProposals;
543
}
544

545
546
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
547
	pub const CouncilMaxProposals: u32 = 100;
548
	pub const CouncilMaxMembers: u32 = 100;
549
550
}

551
type CouncilCollective = pallet_collective::Instance1;
552
impl pallet_collective::Config<CouncilCollective> for Runtime {
553
554
555
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
556
	type MotionDuration = CouncilMotionDuration;
557
	type MaxProposals = CouncilMaxProposals;
558
	type MaxMembers = CouncilMaxMembers;
Wei Tang's avatar
Wei Tang committed
559
	type DefaultVote = pallet_collective::PrimeDefaultVote;
560
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
561
562
}

Gavin Wood's avatar
Gavin Wood committed
563
parameter_types! {
564
	pub const CandidacyBond: Balance = 100 * CENTS;
Kian Paimani's avatar
Kian Paimani committed
565
566
567
568
569
	// 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
570
	pub const TermDuration: BlockNumber = 24 * HOURS;
571
572
	pub const DesiredMembers: u32 = 19;
	pub const DesiredRunnersUp: u32 = 19;
573
	pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect";
574
}
Kian Paimani's avatar
Kian Paimani committed
575

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

579
impl pallet_elections_phragmen::Config for Runtime {
580
	type Event = Event;
581
582
	type Currency = Balances;
	type ChangeMembers = Council;
583
	type InitializeMembers = Council;
584
	type CurrencyToVote = frame_support::traits::U128CurrencyToVote;
Gavin Wood's avatar
Gavin Wood committed
585
	type CandidacyBond = CandidacyBond;
Kian Paimani's avatar
Kian Paimani committed
586
587
	type VotingBondBase = VotingBondBase;
	type VotingBondFactor = VotingBondFactor;
588
589
	type LoserCandidate = Treasury;
	type KickedMember = Treasury;
Gavin Wood's avatar
Gavin Wood committed
590
591
592
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
	type TermDuration = TermDuration;
593
	type PalletId = PhragmenElectionPalletId;
594
	type WeightInfo = weights::pallet_elections_phragmen::WeightInfo<Runtime>;
595
596
}

597
598
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
599
	pub const TechnicalMaxProposals: u32 = 100;
600
	pub const TechnicalMaxMembers: u32 = 100;
601
602
}

603
type TechnicalCollective = pallet_collective::Instance2;
604
impl pallet_collective::Config<TechnicalCollective> for Runtime {
605
606
607
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
608
	type MotionDuration = TechnicalMotionDuration;
609
	type MaxProposals = TechnicalMaxProposals;
610
	type MaxMembers = TechnicalMaxMembers;
Wei Tang's avatar
Wei Tang committed
611
	type DefaultVote = pallet_collective::PrimeDefaultVote;
612
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
613
614
}

615
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
616
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
617
618
619
620
621
	type AddOrigin = MoreThanHalfCouncil;
	type RemoveOrigin = MoreThanHalfCouncil;
	type SwapOrigin = MoreThanHalfCouncil;
	type ResetOrigin = MoreThanHalfCouncil;
	type PrimeOrigin = MoreThanHalfCouncil;
622
623
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
624
	type MaxMembers = TechnicalMaxMembers;
Kian Paimani's avatar
Kian Paimani committed
625
	type WeightInfo = weights::pallet_membership::WeightInfo<Runtime>;
626
627
}

Gavin Wood's avatar
Gavin Wood committed
628
629
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
630
	pub const ProposalBondMinimum: Balance = 2000 * CENTS;
631
	pub const SpendPeriod: BlockNumber = 6 * DAYS;
632
	pub const Burn: Permill = Permill::from_perthousand(2);
Shawn Tabrizi's avatar
Shawn Tabrizi committed
633
	pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
634
635
636

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
637
	pub const TipReportDepositBase: Balance = 100 * CENTS;
638
	pub const DataDepositPerByte: Balance = 1 * CENTS;
639
	pub const BountyDepositBase: Balance = 100 * CENTS;
640
641
642
643
	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);
644
	pub const BountyValueMinimum: Balance = 200 * CENTS;
645
	pub const MaxApprovals: u32 = 100;
Gavin Wood's avatar
Gavin Wood committed
646
647
}

Gavin Wood's avatar
Gavin Wood committed
648
649
650
type ApproveOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
651
	pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
652
653
>;

654
impl pallet_treasury::Config for Runtime {
Shawn Tabrizi's avatar
Shawn Tabrizi committed
655
	type PalletId = TreasuryPalletId;
Gavin Wood's avatar
Gavin Wood committed
656
	type Currency = Balances;
Gavin Wood's avatar
Gavin Wood committed
657
658
	type ApproveOrigin = ApproveOrigin;
	type RejectOrigin = MoreThanHalfCouncil;
659
	type Event = Event;
660
	type OnSlash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
661
662
663
664
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
665
	type BurnDestination = Society;
666
	type MaxApprovals = MaxApprovals;
667
	type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
668
	type SpendFunds = Bounties;
669
670
671
}

impl pallet_bounties::Config for Runtime {
672
673
674
675
676
	type BountyDepositBase = BountyDepositBase;
	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
	type BountyUpdatePeriod = BountyUpdatePeriod;
	type BountyCuratorDeposit = BountyCuratorDeposit;
	type BountyValueMinimum = BountyValueMinimum;
677
	type DataDepositPerByte = DataDepositPerByte;
678
	type Event = Event;
679
680
681
682
683
684
	type MaximumReasonLength = MaximumReasonLength;
	type WeightInfo = weights::pallet_bounties::WeightInfo<Runtime>;
}

impl pallet_tips::Config for Runtime {
	type MaximumReasonLength = MaximumReasonLength;
685
	type DataDepositPerByte = DataDepositPerByte;
686
	type Tippers = PhragmenElection;
687
688
689
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
690
	type Event = Event;
691
	type WeightInfo = weights::pallet_tips::WeightInfo<Runtime>;
692
}
693

694
impl pallet_offences::Config for Runtime {
695
	type Event = Event;
696
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
697
698
699
	type OnOffenceHandler = Staking;
}

700
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
701

702
parameter_types! {
703
	pub NposSolutionPriority: TransactionPriority =
704
		Perbill::from_percent(90) * TransactionPriority::max_value();
705
706
707
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

708
impl pallet_im_online::Config for Runtime {
thiolliere's avatar
thiolliere committed
709
	type AuthorityId = ImOnlineId;
710
	type Event = Event;
711
	type ValidatorSet = Historical;
712
	type NextSessionRotation = Babe;
713
	type ReportUnresponsiveness = Offences;
714
	type UnsignedPriority = ImOnlineUnsignedPriority;
715
	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
716
717
}

718
impl pallet_grandpa::Config for Runtime {
719
	type Event = Event;
720
721
722
723
724
725
726
727
728
729
	type Call = Call;

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

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

730
731
	type KeyOwnerProofSystem = Historical;

732
733
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
734
735

	type WeightInfo = ();
736
737
}

738
739
/// Submits transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
740
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
741
742
	Call: From<LocalCall>,
{
743
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
744
745
746
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
747
		nonce: <Runtime as frame_system::Config>::Index,
748
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
749
		use sp_runtime::traits::StaticLookup;
750
		// take the biggest period possible.
751
752
753
754
755
756
757
		let period = BlockHashCount::get()
			.checked_next_power_of_two()
			.map(|c| c / 2)
			.unwrap_or(2) as u64;

		let current_block = System::block_number()
			.saturated_into::<u64>()
758
759
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
760
761
762
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
763
764
765
766
767
768
769
			frame_system::CheckSpecVersion::<Runtime>::new(),
			frame_system::CheckTxVersion::<Runtime>::new(),
			frame_system::CheckGenesis::<Runtime>::new(),
			frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(period, current_block)),
			frame_system::CheckNonce::<Runtime>::from(nonce),
			frame_system::CheckWeight::<Runtime>::new(),
			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
770
771
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
772
			log::warn!("Unable to create signed payload: {:?}", e);
773
		}).ok()?;
774
775
776
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
777
		let (call, extra, _) = raw_payload.deconstruct();
778
779
		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
		Some((call, (address, signature, extra)))
780
	}
781
782
}

783
impl frame_system::offchain::SigningTypes for Runtime {
784
785
786
787
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

Shawn Tabrizi's avatar