lib.rs 67.7 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
32
	PersistedValidationData, Signature, ValidationCode, ValidationCodeHash, ValidatorId,
	ValidatorIndex, InboundDownwardMessage, InboundHrmpMessage, SessionInfo,
33
};
34
use runtime_common::{
35
36
	claims, paras_registrar, xcm_sender, slots, auctions, crowdloan,
	SlowAdjustingFeeUpdate, CurrencyToVote, impls::DealWithFees,
37
	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,
Martin Pugh's avatar
Martin Pugh committed
123
	spec_version: 9041,
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
	pub const MaxReserves: u32 = 50;
Gavin Wood's avatar
Gavin Wood committed
260
261
}

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

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

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

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

Gavin Wood's avatar
Gavin Wood committed
295
parameter_types! {
296
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
297
298
}

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

306
307
308
309
310
311
parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

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

thiolliere's avatar
thiolliere committed
322
323
324
325
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

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

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

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

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

	// miner configs
	pub const MinerMaxIterations: u32 = 10;
356
	pub OffchainRepeat: BlockNumber = 5;
357
358
}

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

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

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

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

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

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

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

555
556
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
557
	pub const CouncilMaxProposals: u32 = 100;
558
	pub const CouncilMaxMembers: u32 = 100;
559
560
}

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

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

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

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

607
608
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
609
	pub const TechnicalMaxProposals: u32 = 100;
610
	pub const TechnicalMaxMembers: u32 = 100;
611
612
}

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

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

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

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

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

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

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

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

704
impl pallet_offences::Config for Runtime {
705
	type Event = Event;
706
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
707
708
709
	type OnOffenceHandler = Staking;
}

710
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
711

712
parameter_types! {
713
	pub NposSolutionPriority: TransactionPriority =
714
		Perbill::from_percent(90) * TransactionPriority::max_value();
715
716
717
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

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

728
impl pallet_grandpa::Config for Runtime {
729
	type Event = Event;
730
731
732
733
734
735
736
737
738
739
	type Call = Call;

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

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

740
741
	type KeyOwnerProofSystem = Historical;

742
743
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
744
745

	type WeightInfo = ();
746
747
}

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