lib.rs 50.4 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
15
16
// 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
// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.

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

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

Albrecht's avatar
Albrecht committed
23
use pallet_transaction_payment::CurrencyAdapter;
24
use runtime_common::{
25
	claims, SlowAdjustingFeeUpdate, CurrencyToVote,
26
	impls::DealWithFees,
27
	BlockHashCount, RocksDbWeight, BlockWeights, BlockLength, OffchainSolutionWeightLimit,
28
	ParachainSessionKeyPlaceholder, AssignmentSessionKeyPlaceholder,
29
};
Gav Wood's avatar
Gav Wood committed
30

31
use sp_std::prelude::*;
Sergey Pepyakin's avatar
Sergey Pepyakin committed
32
use sp_std::collections::btree_map::BTreeMap;
33
use sp_core::u32_trait::{_1, _2, _3, _4, _5};
34
use parity_scale_codec::{Encode, Decode};
35
use primitives::v1::{
36
37
	AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
	CoreState, GroupRotationInfo, Hash, Id, Moment, Nonce, OccupiedCoreAssumption,
38
	PersistedValidationData, Signature, ValidationCode, ValidatorId, ValidatorIndex,
39
	InboundDownwardMessage, InboundHrmpMessage, SessionInfo,
40
41
42
43
44
45
};
use sp_runtime::{
	create_runtime_str, generic, impl_opaque_keys, ModuleId, ApplyExtrinsicResult,
	KeyTypeId, Percent, Permill, Perbill, curve::PiecewiseLinear,
	transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority},
	traits::{
46
		BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, AccountIdLookup,
47
48
		Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
	},
49
};
50
51
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
52
53
use sp_version::RuntimeVersion;
use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives};
54
#[cfg(any(feature = "std", test))]
55
use sp_version::NativeVersion;
56
57
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
58
use frame_support::{
59
	parameter_types, construct_runtime, RuntimeDebug,
60
	traits::{KeyOwnerProofSystem, Randomness, LockIdentifier, Filter},
61
	weights::Weight,
Gavin Wood's avatar
Gavin Wood committed
62
};
63
use frame_system::{EnsureRoot, EnsureOneOf};
64
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
65
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
66
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
67
use pallet_session::historical as session_historical;
68
use static_assertions::const_assert;
69

Gav Wood's avatar
Gav Wood committed
70
#[cfg(feature = "std")]
71
pub use pallet_staking::StakerStatus;
72
#[cfg(any(feature = "std", test))]
73
pub use sp_runtime::BuildStorage;
74
75
pub use pallet_timestamp::Call as TimestampCall;
pub use pallet_balances::Call as BalancesCall;
76
77
78

/// Constant values used within the runtime.
pub mod constants;
79
use constants::{time::*, currency::*, fee::*};
80
use frame_support::traits::InstanceFilter;
81

82
83
84
// Weights used in the runtime.
mod weights;

85
86
87
88
// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

89
// Polkadot version identifier;
90
/// Runtime version (Polkadot).
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
91
pub const VERSION: RuntimeVersion = RuntimeVersion {
92
93
	spec_name: create_runtime_str!("polkadot"),
	impl_name: create_runtime_str!("parity-polkadot"),
Gavin Wood's avatar
Gavin Wood committed
94
	authoring_version: 0,
95
	spec_version: 30,
96
	impl_version: 0,
97
	#[cfg(not(feature = "disable-runtime-api"))]
98
	apis: RUNTIME_API_VERSIONS,
99
	#[cfg(feature = "disable-runtime-api")]
100
	apis: version::create_apis_vec![[]],
101
	transaction_version: 6,
102
};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
103

104
105
106
107
108
109
110
/// 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
	};

111
112
113
114
115
116
117
118
119
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

120
121
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
Gavin Wood's avatar
Gavin Wood committed
122
	fn filter(call: &Call) -> bool {
123
		match call {
Gavin Wood's avatar
Gavin Wood committed
124
			// These modules are all allowed to be called by transactions:
125
126
			Call::Democracy(_) | Call::Council(_) | Call::TechnicalCommittee(_) |
			Call::TechnicalMembership(_) | Call::Treasury(_) | Call::ElectionsPhragmen(_) |
Gavin Wood's avatar
Gavin Wood committed
127
			Call::System(_) | Call::Scheduler(_) | Call::Indices(_) |
Gavin Wood's avatar
Gavin Wood committed
128
			Call::Babe(_) | Call::Timestamp(_) | Call::Balances(_) |
Gavin Wood's avatar
Gavin Wood committed
129
			Call::Authorship(_) | Call::Staking(_) | Call::Offences(_) |
130
			Call::Session(_) | Call::Grandpa(_) | Call::ImOnline(_) |
Gavin Wood's avatar
Gavin Wood committed
131
			Call::AuthorityDiscovery(_) |
Gavin Wood's avatar
Gavin Wood committed
132
			Call::Utility(_) | Call::Claims(_) | Call::Vesting(_) |
133
			Call::Identity(_) | Call::Proxy(_) | Call::Multisig(_) |
134
			Call::Bounties(_) | Call::Tips(_) | Call::ElectionProviderMultiPhase(_)
135
			=> true,
136
137
138
139
		}
	}
}

Gavin Wood's avatar
Gavin Wood committed
140
141
142
type MoreThanHalfCouncil = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
143
	pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
144
145
>;

146
parameter_types! {
147
	pub const Version: RuntimeVersion = VERSION;
148
	pub const SS58Prefix: u8 = 0;
149
150
}

151
impl frame_system::Config for Runtime {
152
	type BaseCallFilter = BaseFilter;
153
154
	type BlockWeights = BlockWeights;
	type BlockLength = BlockLength;
155
	type Origin = Origin;
156
	type Call = Call;
Gav Wood's avatar
Gav Wood committed
157
	type Index = Nonce;
158
159
160
161
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
162
	type Lookup = AccountIdLookup<AccountId, ()>;
163
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
Gav's avatar
Gav committed
164
	type Event = Event;
165
	type BlockHashCount = BlockHashCount;
166
	type DbWeight = RocksDbWeight;
167
	type Version = Version;
168
	type PalletInfo = PalletInfo;
169
	type AccountData = pallet_balances::AccountData<Balance>;
Gavin Wood's avatar
Gavin Wood committed
170
	type OnNewAccount = ();
171
	type OnKilledAccount = ();
172
	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
173
	type SS58Prefix = SS58Prefix;
174
175
}

176
parameter_types! {
177
178
	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
		BlockWeights::get().max_block;
179
180
181
	pub const MaxScheduledPerBlock: u32 = 50;
}

182
impl pallet_scheduler::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
183
184
	type Event = Event;
	type Origin = Origin;
185
	type PalletsOrigin = OriginCaller;
Gavin Wood's avatar
Gavin Wood committed
186
	type Call = Call;
187
	type MaximumWeight = MaximumSchedulerWeight;
188
	type ScheduleOrigin = EnsureRoot<AccountId>;
189
	type MaxScheduledPerBlock = MaxScheduledPerBlock;
190
	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
Gavin Wood's avatar
Gavin Wood committed
191
192
}

193
parameter_types! {
194
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
195
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
196
197
	pub const ReportLongevity: u64 =
		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
198
199
}

200
impl pallet_babe::Config for Runtime {
201
202
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
203
204

	// session module is the trigger
205
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
206
207
208
209
210

	type KeyOwnerProofSystem = Historical;

	type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
211
		pallet_babe::AuthorityId,
212
213
214
215
	)>>::Proof;

	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
216
		pallet_babe::AuthorityId,
217
218
219
	)>>::IdentificationTuple;

	type HandleEquivocation =
220
		pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
221
222

	type WeightInfo = ();
223
224
}

Gavin Wood's avatar
Gavin Wood committed
225
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
226
	pub const IndexDeposit: Balance = 10 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
227
228
}

229
impl pallet_indices::Config for Runtime {
Gav Wood's avatar
Gav Wood committed
230
	type AccountIndex = AccountIndex;
231
232
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
233
	type Event = Event;
234
	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
Gav Wood's avatar
Gav Wood committed
235
236
}

Gavin Wood's avatar
Gavin Wood committed
237
parameter_types! {
238
	pub const ExistentialDeposit: Balance = 100 * CENTS;
239
	pub const MaxLocks: u32 = 50;
Gavin Wood's avatar
Gavin Wood committed
240
241
}

242
impl pallet_balances::Config for Runtime {
Gav's avatar
Gav committed
243
	type Balance = Balance;
244
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
245
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
246
	type ExistentialDeposit = ExistentialDeposit;
247
	type AccountStore = System;
248
	type MaxLocks = MaxLocks;
249
	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
250
251
252
253
254
255
}

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

256
impl pallet_transaction_payment::Config for Runtime {
Albrecht's avatar
Albrecht committed
257
	type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees<Runtime>>;
Gavin Wood's avatar
Gavin Wood committed
258
	type TransactionByteFee = TransactionByteFee;
259
	type WeightToFee = WeightToFee;
260
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
Gav's avatar
Gav committed
261
262
}

263
parameter_types! {
264
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
265
}
266
impl pallet_timestamp::Config for Runtime {
267
	type Moment = u64;
268
	type OnTimestampSet = Babe;
269
	type MinimumPeriod = MinimumPeriod;
270
	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
271
272
}

Gavin Wood's avatar
Gavin Wood committed
273
parameter_types! {
274
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
275
276
277
}

// TODO: substrate#2986 implement this properly
278
impl pallet_authorship::Config for Runtime {
279
	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
280
281
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
282
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
283
284
}

285
impl_opaque_keys! {
286
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
287
288
289
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
290
291
		pub para_validator: ParachainSessionKeyPlaceholder<Runtime>,
		pub para_assignment: AssignmentSessionKeyPlaceholder<Runtime>,
Gavin Wood's avatar
Gavin Wood committed
292
		pub authority_discovery: AuthorityDiscovery,
293
	}
294
295
}

thiolliere's avatar
thiolliere committed
296
297
298
299
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

300
impl pallet_session::Config for Runtime {
Gav's avatar
Gav committed
301
	type Event = Event;
302
	type ValidatorId = AccountId;
303
	type ValidatorIdOf = pallet_staking::StashOf<Self>;
Gavin Wood's avatar
Gavin Wood committed
304
	type ShouldEndSession = Babe;
305
	type NextSessionRotation = Babe;
306
	type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
Gavin Wood's avatar
Gavin Wood committed
307
308
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
thiolliere's avatar
thiolliere committed
309
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
310
	type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
311
312
}

313
impl pallet_session::historical::Config for Runtime {
314
315
	type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
316
317
}

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
parameter_types! {
	// no signed phase for now, just unsigned.
	pub const SignedPhase: u32 = 0;
	// NOTE: length of unsigned phase is, for now, different than `ElectionLookahead` to make sure
	// that we won't run OCW threads at the same time with staking.
	pub const UnsignedPhase: u32 = ElectionLookahead::get() / 2;

	// fallback: no need to do on-chain phragmen while we re on a dry-run.
	pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy =
		pallet_election_provider_multi_phase::FallbackStrategy::Nothing;

	pub SolutionImprovementThreshold: Perbill = Perbill::from_rational_approximation(1u32, 10_000);

	// miner configs
	pub MultiPhaseUnsignedPriority: TransactionPriority = StakingUnsignedPriority::get() - 1u64;
	pub const MinerMaxIterations: u32 = 10;
}

impl pallet_election_provider_multi_phase::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
	type SignedPhase = SignedPhase;
	type UnsignedPhase = UnsignedPhase;
	type SolutionImprovementThreshold = MinSolutionScoreBump;
	type MinerMaxIterations = MinerMaxIterations;
	type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
	type MinerTxPriority = MultiPhaseUnsignedPriority;
	type DataProvider = Staking;
	type OnChainAccuracy = Perbill;
	type CompactSolution = pallet_staking::CompactAssignments;
	type Fallback = Fallback;
	type BenchmarkingConfig = ();
350
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
351
352
}

353
354
355
// TODO #6469: This shouldn't be static, but a lazily cached value, not built unless needed, and
// re-built in case input parameters have changed. The `ideal_stake` should be determined by the
// amount of parachain slots being bid on: this should be around `(75 - 25.min(slots / 4))%`.
356
pallet_staking_reward_curve::build! {
thiolliere's avatar
thiolliere committed
357
358
359
	const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
		min_inflation: 0_025_000,
		max_inflation: 0_100_000,
360
361
362
		// 3:2:1 staked : parachains : float.
		// while there's no parachains, then this is 75% staked : 25% float.
		ideal_stake: 0_750_000,
thiolliere's avatar
thiolliere committed
363
364
365
366
367
368
		falloff: 0_050_000,
		max_piece_count: 40,
		test_precision: 0_005_000,
	);
}

369
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
370
	// Six sessions in an era (24 hours).
371
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
372
	// 28 eras for unbonding (28 days).
373
374
	pub const BondingDuration: pallet_staking::EraIndex = 28;
	pub const SlashDeferDuration: pallet_staking::EraIndex = 27;
thiolliere's avatar
thiolliere committed
375
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
376
	pub const MaxNominatorRewardedPerValidator: u32 = 128;
joe petrowski's avatar
joe petrowski committed
377
	// last 15 minutes of the last session will be for election.
Gavin Wood's avatar
Gavin Wood committed
378
	pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 16;
379
380
	pub const MaxIterations: u32 = 10;
	pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
381
}
382

Gavin Wood's avatar
Gavin Wood committed
383
384
385
type SlashCancelOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
386
	pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
387
388
>;

389
impl pallet_staking::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
390
	type Currency = Balances;
391
	type UnixTime = Timestamp;
392
	type CurrencyToVote = CurrencyToVote;
Gavin Wood's avatar
Gavin Wood committed
393
	type RewardRemainder = Treasury;
Gav's avatar
Gav committed
394
	type Event = Event;
395
	type Slash = Treasury;
396
	type Reward = ();
397
398
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
399
400
	type SlashDeferDuration = SlashDeferDuration;
	// A super-majority of the council can cancel the slash.
Gavin Wood's avatar
Gavin Wood committed
401
	type SlashCancelOrigin = SlashCancelOrigin;
402
	type SessionInterface = Self;
thiolliere's avatar
thiolliere committed
403
	type RewardCurve = RewardCurve;
Gavin Wood's avatar
Gavin Wood committed
404
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
405
406
407
	type NextNewSession = Session;
	type ElectionLookahead = ElectionLookahead;
	type Call = Call;
408
	type UnsignedPriority = StakingUnsignedPriority;
409
	type MaxIterations = MaxIterations;
410
	type MinSolutionScoreBump = MinSolutionScoreBump;
411
412
413
	// The unsigned solution weight targeted by the OCW. We set it to the maximum possible value of
	// a single extrinsic.
	type OffchainSolutionWeightLimit = OffchainSolutionWeightLimit;
414
	type ElectionProvider = ElectionProviderMultiPhase;
415
	type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
416
417
}

Gavin Wood's avatar
Gavin Wood committed
418
419
420
421
422
423
424
425
426
427
parameter_types! {
	// Minimum 4 CENTS/byte
	pub const BasicDeposit: Balance = deposit(1, 258);
	pub const FieldDeposit: Balance = deposit(0, 66);
	pub const SubAccountDeposit: Balance = deposit(1, 53);
	pub const MaxSubAccounts: u32 = 100;
	pub const MaxAdditionalFields: u32 = 100;
	pub const MaxRegistrars: u32 = 20;
}

428
impl pallet_identity::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
429
430
431
432
433
434
435
436
437
	type Event = Event;
	type Currency = Balances;
	type BasicDeposit = BasicDeposit;
	type FieldDeposit = FieldDeposit;
	type SubAccountDeposit = SubAccountDeposit;
	type MaxSubAccounts = MaxSubAccounts;
	type MaxAdditionalFields = MaxAdditionalFields;
	type MaxRegistrars = MaxRegistrars;
	type Slashed = Treasury;
Gavin Wood's avatar
Gavin Wood committed
438
439
	type ForceOrigin = MoreThanHalfCouncil;
	type RegistrarOrigin = MoreThanHalfCouncil;
440
	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
Gavin Wood's avatar
Gavin Wood committed
441
442
}

443
parameter_types! {
444
445
	pub const LaunchPeriod: BlockNumber = 28 * DAYS;
	pub const VotingPeriod: BlockNumber = 28 * DAYS;
446
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
447
	pub const MinimumDeposit: Balance = 100 * DOLLARS;
Gav Wood's avatar
Gav Wood committed
448
	pub const EnactmentPeriod: BlockNumber = 28 * DAYS;
449
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
450
451
	// One cent: $10,000 / MB
	pub const PreimageByteDeposit: Balance = 1 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
452
	pub const InstantAllowed: bool = true;
453
	pub const MaxVotes: u32 = 100;
454
	pub const MaxProposals: u32 = 100;
455
456
}

457
impl pallet_democracy::Config for Runtime {
458
459
	type Proposal = Call;
	type Event = Event;
460
	type Currency = Balances;
461
462
463
464
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
	type MinimumDeposit = MinimumDeposit;
465
	/// A straight majority of the council can decide what their next motion is.
466
467
468
	type ExternalOrigin = frame_system::EnsureOneOf<AccountId,
		pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>,
		frame_system::EnsureRoot<AccountId>,
Gavin Wood's avatar
Gavin Wood committed
469
	>;
470
	/// A 60% super-majority can have the next scheduled referendum be a straight majority-carries vote.
471
472
473
	type ExternalMajorityOrigin = frame_system::EnsureOneOf<AccountId,
		pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>,
		frame_system::EnsureRoot<AccountId>,
Gavin Wood's avatar
Gavin Wood committed
474
	>;
475
476
	/// A unanimous council can have the next scheduled referendum be a straight default-carries
	/// (NTB) vote.
477
478
479
	type ExternalDefaultOrigin = frame_system::EnsureOneOf<AccountId,
		pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>,
		frame_system::EnsureRoot<AccountId>,
Gavin Wood's avatar
Gavin Wood committed
480
	>;
481
482
	/// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote
	/// be tabled immediately and with a shorter voting/enactment period.
483
484
485
	type FastTrackOrigin = frame_system::EnsureOneOf<AccountId,
		pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>,
		frame_system::EnsureRoot<AccountId>,
Gavin Wood's avatar
Gavin Wood committed
486
	>;
487
488
489
	type InstantOrigin = frame_system::EnsureOneOf<AccountId,
		pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>,
		frame_system::EnsureRoot<AccountId>,
Gavin Wood's avatar
Gavin Wood committed
490
	>;
491
492
	type InstantAllowed = InstantAllowed;
	type FastTrackVotingPeriod = FastTrackVotingPeriod;
493
	// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
494
	type CancellationOrigin = EnsureOneOf<AccountId,
495
		pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
496
497
498
499
500
501
502
		EnsureRoot<AccountId>,
	>;
	// To cancel a proposal before it has been passed, the technical committee must be unanimous or
	// Root must agree.
	type CancelProposalOrigin = EnsureOneOf<AccountId,
		pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>,
		EnsureRoot<AccountId>,
Gavin Wood's avatar
Gavin Wood committed
503
	>;
504
	type BlacklistOrigin = EnsureRoot<AccountId>;
505
506
	// 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.
507
	type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
508
	type CooloffPeriod = CooloffPeriod;
Gavin Wood's avatar
Gavin Wood committed
509
	type PreimageByteDeposit = PreimageByteDeposit;
510
	type OperationalPreimageOrigin = pallet_collective::EnsureMember<AccountId, CouncilCollective>;
Gavin Wood's avatar
Gavin Wood committed
511
	type Slash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
512
	type Scheduler = Scheduler;
513
	type PalletsOrigin = OriginCaller;
514
	type MaxVotes = MaxVotes;
515
516
	type WeightInfo = weights::pallet_democracy::WeightInfo<Runtime>;
	type MaxProposals = MaxProposals;
517
}
518

519
520
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 7 * DAYS;
521
	pub const CouncilMaxProposals: u32 = 100;
522
	pub const CouncilMaxMembers: u32 = 100;
523
524
}

525
type CouncilCollective = pallet_collective::Instance1;
526
impl pallet_collective::Config<CouncilCollective> for Runtime {
527
528
529
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
530
	type MotionDuration = CouncilMotionDuration;
531
	type MaxProposals = CouncilMaxProposals;
532
	type MaxMembers = CouncilMaxMembers;
Wei Tang's avatar
Wei Tang committed
533
	type DefaultVote = pallet_collective::PrimeDefaultVote;
534
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
535
536
}

Gavin Wood's avatar
Gavin Wood committed
537
parameter_types! {
538
	pub const CandidacyBond: Balance = 100 * DOLLARS;
Kian Paimani's avatar
Kian Paimani committed
539
540
541
542
	// 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);
Gavin Wood's avatar
Gavin Wood committed
543
544
	/// Weekly council elections; scaling up to monthly eventually.
	pub const TermDuration: BlockNumber = 7 * DAYS;
545
	/// 13 members initially, to be increased to 23 eventually.
546
	pub const DesiredMembers: u32 = 13;
547
	pub const DesiredRunnersUp: u32 = 20;
548
	pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
549
}
550
551
// Make sure that there are no more than `MaxMembers` members elected via phragmen.
const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get());
552

553
impl pallet_elections_phragmen::Config for Runtime {
554
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
555
	type ModuleId = ElectionsPhragmenModuleId;
556
557
	type Currency = Balances;
	type ChangeMembers = Council;
558
	type InitializeMembers = Council;
559
	type CurrencyToVote = frame_support::traits::U128CurrencyToVote;
Gavin Wood's avatar
Gavin Wood committed
560
	type CandidacyBond = CandidacyBond;
Kian Paimani's avatar
Kian Paimani committed
561
562
	type VotingBondBase = VotingBondBase;
	type VotingBondFactor = VotingBondFactor;
563
564
	type LoserCandidate = Treasury;
	type KickedMember = Treasury;
Gavin Wood's avatar
Gavin Wood committed
565
566
567
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
	type TermDuration = TermDuration;
568
	type WeightInfo = weights::pallet_elections_phragmen::WeightInfo<Runtime>;
569
570
}

571
572
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 7 * DAYS;
573
	pub const TechnicalMaxProposals: u32 = 100;
574
	pub const TechnicalMaxMembers: u32 = 100;
575
576
}

577
type TechnicalCollective = pallet_collective::Instance2;
578
impl pallet_collective::Config<TechnicalCollective> for Runtime {
579
580
581
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
582
	type MotionDuration = TechnicalMotionDuration;
583
	type MaxProposals = TechnicalMaxProposals;
584
	type MaxMembers = TechnicalMaxMembers;
Wei Tang's avatar
Wei Tang committed
585
	type DefaultVote = pallet_collective::PrimeDefaultVote;
586
	type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
587
588
}

589
impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
590
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
591
592
593
594
595
	type AddOrigin = MoreThanHalfCouncil;
	type RemoveOrigin = MoreThanHalfCouncil;
	type SwapOrigin = MoreThanHalfCouncil;
	type ResetOrigin = MoreThanHalfCouncil;
	type PrimeOrigin = MoreThanHalfCouncil;
596
597
598
599
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
}

Gavin Wood's avatar
Gavin Wood committed
600
601
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
602
603
604
	pub const ProposalBondMinimum: Balance = 100 * DOLLARS;
	pub const SpendPeriod: BlockNumber = 24 * DAYS;
	pub const Burn: Permill = Permill::from_percent(1);
605
	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
606
607
608
609

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
	pub const TipReportDepositBase: Balance = 1 * DOLLARS;
610
611
612
613
614
615
616
	pub const DataDepositPerByte: Balance = 1 * CENTS;
	pub const BountyDepositBase: Balance = 1 * DOLLARS;
	pub const BountyDepositPayoutDelay: BlockNumber = 8 * DAYS;
	pub const BountyUpdatePeriod: BlockNumber = 90 * DAYS;
	pub const MaximumReasonLength: u32 = 16384;
	pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
	pub const BountyValueMinimum: Balance = 10 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
617
618
}

Gavin Wood's avatar
Gavin Wood committed
619
620
621
type ApproveOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
622
	pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
623
624
>;

625
impl pallet_treasury::Config for Runtime {
Gavin Wood's avatar
Gavin Wood committed
626
	type ModuleId = TreasuryModuleId;
Gavin Wood's avatar
Gavin Wood committed
627
	type Currency = Balances;
Gavin Wood's avatar
Gavin Wood committed
628
629
	type ApproveOrigin = ApproveOrigin;
	type RejectOrigin = MoreThanHalfCouncil;
630
	type Event = Event;
631
	type OnSlash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
632
633
634
635
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
636
637
638
639
640
641
642
	type BurnDestination = ();
	type SpendFunds = Bounties;
	type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
}

impl pallet_bounties::Config for Runtime {
	type Event = Event;
643
644
645
646
647
	type BountyDepositBase = BountyDepositBase;
	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
	type BountyUpdatePeriod = BountyUpdatePeriod;
	type BountyCuratorDeposit = BountyCuratorDeposit;
	type BountyValueMinimum = BountyValueMinimum;
648
649
650
651
652
653
654
655
656
657
658
659
660
661
	type DataDepositPerByte = DataDepositPerByte;
	type MaximumReasonLength = MaximumReasonLength;
	type WeightInfo = weights::pallet_bounties::WeightInfo<Runtime>;
}

impl pallet_tips::Config for Runtime {
	type Event = Event;
	type DataDepositPerByte = DataDepositPerByte;
	type MaximumReasonLength = MaximumReasonLength;
	type Tippers = ElectionsPhragmen;
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
	type WeightInfo = weights::pallet_tips::WeightInfo<Runtime>;
662
}
663

664
parameter_types! {
665
	pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * BlockWeights::get().max_block;
666
667
}

668
impl pallet_offences::Config for Runtime {
669
	type Event = Event;
670
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
671
	type OnOffenceHandler = Staking;
672
	type WeightSoftLimit = OffencesWeightSoftLimit;
673
674
}

675
impl pallet_authority_discovery::Config for Runtime {}
Gavin Wood's avatar
Gavin Wood committed
676

677
678
679
680
parameter_types! {
	pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _;
}

681
parameter_types! {
682
683
	pub StakingUnsignedPriority: TransactionPriority =
		Perbill::from_percent(90) * TransactionPriority::max_value();
684
685
686
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

687
impl pallet_im_online::Config for Runtime {
thiolliere's avatar
thiolliere committed
688
	type AuthorityId = ImOnlineId;
689
	type Event = Event;
690
	type ValidatorSet = Historical;
691
	type SessionDuration = SessionDuration;
Gavin Wood's avatar
Gavin Wood committed
692
	type ReportUnresponsiveness = Offences;
693
	type UnsignedPriority = ImOnlineUnsignedPriority;
694
	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
695
696
}

697
impl pallet_grandpa::Config for Runtime {
698
	type Event = Event;
699
700
701
	type Call = Call;

	type KeyOwnerProof =
Gavin Wood's avatar
Gavin Wood committed
702
	<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
703
704
705
706
707
708

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

Gavin Wood's avatar
Gavin Wood committed
709
710
	type KeyOwnerProofSystem = Historical;

711
712
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
713
714

	type WeightInfo = ();
715
716
}

717
718
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
719
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
720
721
	Call: From<LocalCall>,
{
722
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
723
724
725
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
726
		nonce: <Runtime as frame_system::Config>::Index,
727
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
728
		use sp_runtime::traits::StaticLookup;
729
		// take the biggest period possible.
730
731
732
733
734
735
736
		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>()
737
738
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
739
740
741
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
742
743
744
745
746
747
748
			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),
749
			claims::PrevalidateAttests::<Runtime>::new(),
750
751
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
752
			log::warn!("Unable to create signed payload: {:?}", e);
753
		}).ok()?;
754
755
756
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
757
		let (call, extra, _) = raw_payload.deconstruct();
758
759
		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
		Some((call, (address, signature, extra)))
760
	}
761
762
}

763
impl frame_system::offchain::SigningTypes for Runtime {
764
765
766
767
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

768
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where Call: From<C> {
769
	type Extrinsic = UncheckedExtrinsic;
Gavin Wood's avatar
Gavin Wood committed
770
	type OverarchingCall = Call;
771
772
}

773
774
775
776
777
778
parameter_types! {
	pub const ParathreadDeposit: Balance = 500 * DOLLARS;
	pub const QueueSize: usize = 2;
	pub const MaxRetries: u32 = 3;
}

Gavin Wood's avatar
Gavin Wood committed
779
parameter_types! {
780
	pub Prefix: &'static [u8] = b"Pay DOTs to the Polkadot account:";
781
782
}

783
impl claims::Config for Runtime {
784
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
785
	type VestingSchedule = Vesting;
786
	type Prefix = Prefix;
787
	/// At least 3/4 of the council must agree to a claim move before it can happen.
788
	type MoveClaimOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
789
	type WeightInfo = weights::runtime_common_claims::WeightInfo<Runtime>;
790
791
}

792
793
794
795
parameter_types! {
	pub const MinVestedTransfer: Balance = 100 * DOLLARS;
}

796
impl pallet_vesting::Config for Runtime