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

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

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

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

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

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

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

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;

56
use xcm::v0::{MultiLocation, NetworkId, BodyId, Xcm, MultiAsset};
57
58
use xcm_builder::{
	AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter,
59
60
	ChildParachainAsNative, SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter,
	IsConcrete, FixedWeightBounds, TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
61
	IsChildSystemParachain, UsingComponents, BackingToPlurality, SignedToAccountId32,
62
63
};
use xcm_executor::XcmExecutor;
64
use sp_arithmetic::Perquintill;
65
use sp_runtime::{
Shawn Tabrizi's avatar
Shawn Tabrizi committed
66
	create_runtime_str, generic, impl_opaque_keys,
67
	ApplyExtrinsicResult, KeyTypeId, Percent, Permill, Perbill,
Gavin Wood's avatar
Gavin Wood committed
68
	transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority},
69
	traits::{
70
		BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, AccountIdLookup,
Gavin Wood's avatar
Gavin Wood committed
71
		Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
72
	},
Gav Wood's avatar
Gav Wood committed
73
};
74
75
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
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;
93
94
use beefy_primitives::ecdsa::AuthorityId as BeefyId;
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;
102
103
104

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

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

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

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

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

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

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

147
/// Don't allow swaps until parathread story is more mature.
148
149
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
150
151
	fn filter(c: &Call) -> bool {
		!matches!(c,
152
			Call::Registrar(paras_registrar::Call::swap(..))
153
		)
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
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) {
429
430
431
		// 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();
432
433
434
435
436
437
438
439
		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),
440
			auctioned_slots,
441
442
		)
	}
thiolliere's avatar
thiolliere committed
443
444
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

731
732
	type KeyOwnerProofSystem = Historical;

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

	type WeightInfo = ();
737
738
}

739
740
/// Submits transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
741
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
742
743
	Call: From<LocalCall>,
{
744
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
745
746
747
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
748
		nonce: <Runtime as frame_system::Config>::Index,
749
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
750
		use sp_runtime::traits::StaticLookup;
751
		// take the biggest period possible.
752
753
754
755
756
757
758
		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>()
759
760
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
761
762
763
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
764
765
766
767
768
769
770
			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),
771
772
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
773
			log::warn!("Unable to create signed payload: {:?}", e);
774
		}).ok()?;
775
776
777
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
778
		let (call, extra, _) = raw_payload.deconstruct();
779
780
		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
		Some((call, (address, signature, extra)))