lib.rs 66.9 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: 9050,
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
}

Qinxuan Chen's avatar
Qinxuan Chen committed
195
196
impl pallet_randomness_collective_flip::Config for Runtime {}

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

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

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

221
impl pallet_babe::Config for Runtime {
222
223
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
224
225

	// session module is the trigger
226
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
227
228
229

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

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

238
239
	type KeyOwnerProofSystem = Historical;

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

	type WeightInfo = ();
244
245
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

370
371
372
373
impl pallet_election_provider_multi_phase::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
	type UnsignedPhase = UnsignedPhase;
374
	type SignedPhase = SignedPhase;
375
	type SolutionImprovementThreshold = SolutionImprovementThreshold;
376
	type MinerMaxIterations = MinerMaxIterations;
377
	type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
378
	type MinerMaxLength = OffchainSolutionLengthLimit;
379
	type OffchainRepeat = OffchainRepeat;
380
	type MinerTxPriority = NposSolutionPriority;
381
	type DataProvider = Staking;
Kian Paimani's avatar
Kian Paimani committed
382
	type CompactSolution = NposCompactSolution24;
383
	type OnChainAccuracy = Perbill;
384
385
	type Fallback = Fallback;
	type BenchmarkingConfig = ();
386
387
388
389
390
	type ForceOrigin = EnsureOneOf<
		AccountId,
		EnsureRoot<AccountId>,
		pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
	>;
391
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
392
393
}

394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
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) {
440
441
442
		// 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();
443
444
445
446
447
448
449
450
		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),
451
			auctioned_slots,
452
453
		)
	}
thiolliere's avatar
thiolliere committed
454
455
}

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

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

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

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

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

561
562
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 3 * DAYS;
563
	pub const CouncilMaxProposals: u32 = 100;
564
	pub const CouncilMaxMembers: u32 = 100;
565
566
}

567
type CouncilCollective = pallet_collective::Instance1;
568
impl pallet_collective::Config<CouncilCollective> for Runtime {
569
570
571
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
572
	type MotionDuration = CouncilMotionDuration;
573
	type MaxProposals = CouncilMaxProposals;
574
	type MaxMembers = CouncilMaxMembers;
Wei Tang's avatar
Wei Tang committed
575
	type DefaultVote = pallet_collective::PrimeDefaultVote;
576
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
577
578
}

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

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

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

613
614
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS;
615
	pub const TechnicalMaxProposals: u32 = 100;
616
	pub const TechnicalMaxMembers: u32 = 100;
617
618
}

619
type TechnicalCollective = pallet_collective::Instance2;
620
impl pallet_collective::Config<TechnicalCollective> for Runtime {
621
622
623
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
624
	type MotionDuration = TechnicalMotionDuration;
625
	type MaxProposals = TechnicalMaxProposals;
626
	type MaxMembers = TechnicalMaxMembers;
Wei Tang's avatar
Wei Tang committed
627
	type DefaultVote = pallet_collective::PrimeDefaultVote;
628
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
629
630
}

631
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
632
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
633
634
635
636
637
	type AddOrigin = MoreThanHalfCouncil;
	type RemoveOrigin = MoreThanHalfCouncil;
	type SwapOrigin = MoreThanHalfCouncil;
	type ResetOrigin = MoreThanHalfCouncil;
	type PrimeOrigin = MoreThanHalfCouncil;
638
639
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
640
	type MaxMembers = TechnicalMaxMembers;
Kian Paimani's avatar
Kian Paimani committed
641
	type WeightInfo = weights::pallet_membership::WeightInfo<Runtime>;
642
643
}

Gavin Wood's avatar
Gavin Wood committed
644
645
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
646
	pub const ProposalBondMinimum: Balance = 2000 * CENTS;
647
	pub const SpendPeriod: BlockNumber = 6 * DAYS;
648
	pub const Burn: Permill = Permill::from_perthousand(2);
Shawn Tabrizi's avatar
Shawn Tabrizi committed
649
	pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
650
651
652

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
653
	pub const TipReportDepositBase: Balance = 100 * CENTS;
654
	pub const DataDepositPerByte: Balance = 1 * CENTS;
655
	pub const BountyDepositBase: Balance = 100 * CENTS;
656
657
658
659
	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);
660
	pub const BountyValueMinimum: Balance = 200 * CENTS;
661
	pub const MaxApprovals: u32 = 100;
Gavin Wood's avatar
Gavin Wood committed
662
663
}

Gavin Wood's avatar
Gavin Wood committed
664
665
666
type ApproveOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
667
	pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
668
669
>;

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

impl pallet_bounties::Config for Runtime {
688
689
690
691
692
	type BountyDepositBase = BountyDepositBase;
	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
	type BountyUpdatePeriod = BountyUpdatePeriod;
	type BountyCuratorDeposit = BountyCuratorDeposit;
	type BountyValueMinimum = BountyValueMinimum;
693
	type DataDepositPerByte = DataDepositPerByte;
694
	type Event = Event;
695
696
697
698
699
700
	type MaximumReasonLength = MaximumReasonLength;
	type WeightInfo = weights::pallet_bounties::WeightInfo<Runtime>;
}

impl pallet_tips::Config for Runtime {
	type MaximumReasonLength = MaximumReasonLength;
701
	type DataDepositPerByte = DataDepositPerByte;
702
	type Tippers = PhragmenElection;
703
704
705
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
706
	type Event = Event;
707
	type WeightInfo = weights::pallet_tips::WeightInfo<Runtime>;
708
}
709

710
impl pallet_offences::Config for Runtime {
711
	type Event = Event;
712
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
713
714
715
	type OnOffenceHandler = Staking;
}

716
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
717

718
parameter_types! {
719
	pub NposSolutionPriority: TransactionPriority =
720
		Perbill::from_percent(90) * TransactionPriority::max_value();
721
722
723
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

724
impl pallet_im_online::Config for Runtime {
thiolliere's avatar
thiolliere committed
725
	type AuthorityId = ImOnlineId;
726
	type Event = Event;
727
	type ValidatorSet = Historical;
728
	type NextSessionRotation = Babe;
729
	type ReportUnresponsiveness = Offences;
730
	type UnsignedPriority = ImOnlineUnsignedPriority;
731
	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
732
733
}

734
impl pallet_grandpa::Config for Runtime {
735
	type Event = Event;
736
737
738
739
740
741
742
743
744
745
	type Call = Call;

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

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

746
747
	type KeyOwnerProofSystem = Historical;

748
749
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
750
751

	type WeightInfo = ();
752
753
}

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