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

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

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

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

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

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

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

132
133
134
135
136
137
138
/// The BABE epoch configuration at genesis.
pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration =
	babe_primitives::BabeEpochConfiguration {
		c: PRIMARY_PROBABILITY,
		allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots
	};

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

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

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

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

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

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

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

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

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

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

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

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

236
237
	type KeyOwnerProofSystem = Historical;

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

	type WeightInfo = ();
242
243
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

365
366
367
368
impl pallet_election_provider_multi_phase::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
	type UnsignedPhase = UnsignedPhase;
369
	type SignedPhase = SignedPhase;
370
	type SolutionImprovementThreshold = SolutionImprovementThreshold;
371
	type MinerMaxIterations = MinerMaxIterations;
372
	type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
373
	type MinerMaxLength = OffchainSolutionLengthLimit;
374
	type OffchainRepeat = OffchainRepeat;
375
	type MinerTxPriority = NposSolutionPriority;
376
	type DataProvider = Staking;
Kian Paimani's avatar
Kian Paimani committed
377
	type CompactSolution = NposCompactSolution24;
378
	type OnChainAccuracy = Perbill;
379
380
	type Fallback = Fallback;
	type BenchmarkingConfig = ();
381
382
383
384
385
	type ForceOrigin = EnsureOneOf<
		AccountId,
		EnsureRoot<AccountId>,
		pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
	>;
386
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
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
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) {
435
436
437
		// 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();
438
439
440
441
442
443
444
445
		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),
446
			auctioned_slots,
447
448
		)
	}
thiolliere's avatar
thiolliere committed
449
450
}

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

Gavin Wood's avatar
Gavin Wood committed
461
462
463
type SlashCancelOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
464
	pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
465
466
>;

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

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

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

552
553
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
554
	pub const CouncilMaxProposals: u32 = 100;
555
	pub const CouncilMaxMembers: u32 = 100;
556
557
}

558
type CouncilCollective = pallet_collective::Instance1;
559
impl pallet_collective::Config<CouncilCollective> for Runtime {
560
561
562
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
563
	type MotionDuration = CouncilMotionDuration;
564
	type MaxProposals = CouncilMaxProposals;
565
	type MaxMembers = CouncilMaxMembers;
Wei Tang's avatar
Wei Tang committed
566
	type DefaultVote = pallet_collective::PrimeDefaultVote;
567
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
568
569
}

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

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

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

604
605
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
606
	pub const TechnicalMaxProposals: u32 = 100;
607
	pub const TechnicalMaxMembers: u32 = 100;
608
609
}

610
type TechnicalCollective = pallet_collective::Instance2;
611
impl pallet_collective::Config<TechnicalCollective> for Runtime {
612
613
614
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
615
	type MotionDuration = TechnicalMotionDuration;
616
	type MaxProposals = TechnicalMaxProposals;
617
	type MaxMembers = TechnicalMaxMembers;
Wei Tang's avatar
Wei Tang committed
618
	type DefaultVote = pallet_collective::PrimeDefaultVote;
619
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
620
621
}

622
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
623
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
624
625
626
627
628
	type AddOrigin = MoreThanHalfCouncil;
	type RemoveOrigin = MoreThanHalfCouncil;
	type SwapOrigin = MoreThanHalfCouncil;
	type ResetOrigin = MoreThanHalfCouncil;
	type PrimeOrigin = MoreThanHalfCouncil;
629
630
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
631
	type MaxMembers = TechnicalMaxMembers;
Kian Paimani's avatar
Kian Paimani committed
632
	type WeightInfo = weights::pallet_membership::WeightInfo<Runtime>;
633
634
}

Gavin Wood's avatar
Gavin Wood committed
635
636
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
637
	pub const ProposalBondMinimum: Balance = 2000 * CENTS;
638
	pub const SpendPeriod: BlockNumber = 6 * DAYS;
639
	pub const Burn: Permill = Permill::from_perthousand(2);
Shawn Tabrizi's avatar
Shawn Tabrizi committed
640
	pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
641
642
643

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
644
	pub const TipReportDepositBase: Balance = 100 * CENTS;
645
	pub const DataDepositPerByte: Balance = 1 * CENTS;
646
	pub const BountyDepositBase: Balance = 100 * CENTS;
647
648
649
650
	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);
651
	pub const BountyValueMinimum: Balance = 200 * CENTS;
652
	pub const MaxApprovals: u32 = 100;
Gavin Wood's avatar
Gavin Wood committed
653
654
}

Gavin Wood's avatar
Gavin Wood committed
655
656
657
type ApproveOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
658
	pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
659
660
>;

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

impl pallet_bounties::Config for Runtime {
679
680
681
682
683
	type BountyDepositBase = BountyDepositBase;
	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
	type BountyUpdatePeriod = BountyUpdatePeriod;
	type BountyCuratorDeposit = BountyCuratorDeposit;
	type BountyValueMinimum = BountyValueMinimum;
684
	type DataDepositPerByte = DataDepositPerByte;
685
	type Event = Event;
686
687
688
689
690
691
	type MaximumReasonLength = MaximumReasonLength;
	type WeightInfo = weights::pallet_bounties::WeightInfo<Runtime>;
}

impl pallet_tips::Config for Runtime {
	type MaximumReasonLength = MaximumReasonLength;
692
	type DataDepositPerByte = DataDepositPerByte;
693
	type Tippers = PhragmenElection;
694
695
696
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
697
	type Event = Event;
698
	type WeightInfo = weights::pallet_tips::WeightInfo<Runtime>;
699
}
700

701
impl pallet_offences::Config for Runtime {
702
	type Event = Event;
703
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
704
705
706
	type OnOffenceHandler = Staking;
}

707
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
708

709
parameter_types! {
710
	pub NposSolutionPriority: TransactionPriority =
711
		Perbill::from_percent(90) * TransactionPriority::max_value();
712
713
714
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

715
impl pallet_im_online::Config for Runtime {
thiolliere's avatar
thiolliere committed
716
	type AuthorityId = ImOnlineId;
717
	type Event = Event;
718
	type ValidatorSet = Historical;
719
	type NextSessionRotation = Babe;
720
	type ReportUnresponsiveness = Offences;
721
	type UnsignedPriority = ImOnlineUnsignedPriority;
722
	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
723
724
}

725
impl pallet_grandpa::Config for Runtime {
726
	type Event = Event;
727
728
729
730
731
732
733
734
735
736
	type Call = Call;

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

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

737
738
	type KeyOwnerProofSystem = Historical;

739
740
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
741
742

	type WeightInfo = ();
743
744
}

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