lib.rs 42.3 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
21
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit="256"]
Gav Wood's avatar
Gav Wood committed
22

23
24
25
use runtime_common::{
	attestations, claims, parachains, registrar, slots, SlowAdjustingFeeUpdate,
	impls::{CurrencyToVoteHandler, ToAuthor},
26
	NegativeImbalance, BlockHashCount, MaximumBlockWeight, AvailableBlockRatio,
27
	MaximumBlockLength, BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight,
28
	MaximumExtrinsicWeight,
29
};
Gav Wood's avatar
Gav Wood committed
30

31
use sp_std::prelude::*;
32
use sp_core::u32_trait::{_1, _2, _3, _4, _5};
33
use codec::{Encode, Decode};
34
use primitives::{
35
	AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
Gavin Wood's avatar
Gavin Wood committed
36
	parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext},
37
};
38
use sp_runtime::{
39
	create_runtime_str, generic, impl_opaque_keys, ModuleId,
40
41
	ApplyExtrinsicResult, KeyTypeId, Percent, Permill, Perbill,
		transaction_validity::{
Gavin Wood's avatar
Gavin Wood committed
42
		TransactionValidity, TransactionSource, TransactionPriority,
43
	},
44
	curve::PiecewiseLinear,
45
	traits::{
Gavin Wood's avatar
Gavin Wood committed
46
47
		BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, IdentityLookup,
		Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
48
	},
Gav Wood's avatar
Gav Wood committed
49
};
50
51
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::RuntimeString;
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
52
use version::RuntimeVersion;
53
use grandpa::{AuthorityId as GrandpaId, fg_primitives};
54
55
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
56
57
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
58
use frame_support::{
59
	parameter_types, construct_runtime, debug, RuntimeDebug,
Gavin Wood's avatar
Gavin Wood committed
60
	traits::{KeyOwnerProofSystem, SplitTwoWays, Randomness, LockIdentifier, Filter},
61
	weights::Weight,
Gavin Wood's avatar
Gavin Wood committed
62
};
Gavin Wood's avatar
Gavin Wood committed
63
use system::{EnsureRoot, EnsureOneOf};
thiolliere's avatar
thiolliere committed
64
use im_online::sr25519::AuthorityId as ImOnlineId;
Gavin Wood's avatar
Gavin Wood committed
65
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
Gavin Wood's avatar
Gavin Wood committed
66
use transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
67
use session::historical as session_historical;
68
use static_assertions::const_assert;
69

Gav Wood's avatar
Gav Wood committed
70
71
#[cfg(feature = "std")]
pub use staking::StakerStatus;
72
#[cfg(any(feature = "std", test))]
73
pub use sp_runtime::BuildStorage;
74
pub use timestamp::Call as TimestampCall;
75
pub use balances::Call as BalancesCall;
76
pub use attestations::{Call as AttestationsCall, MORE_ATTESTATIONS_IDENTIFIER};
77
pub use parachains::Call as ParachainsCall;
78
79
80

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

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

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

103
104
105
106
107
108
109
110
111
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

112
113
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
Gavin Wood's avatar
Gavin Wood committed
114
	fn filter(call: &Call) -> bool {
115
		match call {
Gavin Wood's avatar
Gavin Wood committed
116
117
118
119
120
121
			Call::Parachains(parachains::Call::set_heads(..))
				| Call::Democracy(democracy::Call::vote(..))
				| Call::Democracy(democracy::Call::remove_vote(..))
				| Call::Democracy(democracy::Call::delegate(..))
				| Call::Democracy(democracy::Call::undelegate(..))
				=> true,
Gavin Wood's avatar
Gavin Wood committed
122

Gavin Wood's avatar
Gavin Wood committed
123
124
125
126
127
128
			// Governance stuff
			Call::Democracy(_) | Call::Council(_) | Call::TechnicalCommittee(_) |
			Call::ElectionsPhragmen(_) | Call::TechnicalMembership(_) | Call::Treasury(_) |
			// Parachains stuff
			Call::Parachains(_) | Call::Attestations(_) | Call::Slots(_) | Call::Registrar(_) |
			// Balances and Vesting's transfer (which can be used to transfer)
Gavin Wood's avatar
Gavin Wood committed
129
130
			Call::Balances(_) | Call::Vesting(vesting::Call::vested_transfer(..)) |
			Call::Indices(indices::Call::transfer(..)) =>
Gavin Wood's avatar
Gavin Wood committed
131
132
133
134
135
136
137
138
				false,

			// These modules are all allowed to be called by transactions:
			Call::System(_) | Call::Scheduler(_) | Call::Indices(_) |
			Call::Babe(_) | Call::Timestamp(_) |
			Call::Authorship(_) | Call::Staking(_) | Call::Offences(_) |
			Call::Session(_) | Call::FinalityTracker(_) | Call::Grandpa(_) | Call::ImOnline(_) |
			Call::AuthorityDiscovery(_) |
Gavin Wood's avatar
Gavin Wood committed
139
			Call::Utility(_) | Call::Claims(_) | Call::Vesting(_) | Call::Sudo(_) |
140
			Call::Identity(_) | Call::Proxy(_) | Call::Multisig(_) =>
Gavin Wood's avatar
Gavin Wood committed
141
				true,
142
143
144
145
		}
	}
}

Gavin Wood's avatar
Gavin Wood committed
146
147
148
149
150
151
type MoreThanHalfCouncil = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
	collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
>;

152
parameter_types! {
153
	pub const Version: RuntimeVersion = VERSION;
154
155
}

156
impl system::Trait for Runtime {
157
	type BaseCallFilter = BaseFilter;
158
	type Origin = Origin;
159
	type Call = Call;
Gav Wood's avatar
Gav Wood committed
160
	type Index = Nonce;
161
162
163
164
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
165
	type Lookup = IdentityLookup<AccountId>;
166
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
Gav's avatar
Gav committed
167
	type Event = Event;
168
	type BlockHashCount = BlockHashCount;
169
	type MaximumBlockWeight = MaximumBlockWeight;
170
	type DbWeight = RocksDbWeight;
171
172
	type BlockExecutionWeight = BlockExecutionWeight;
	type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
Tomasz Drwięga's avatar
Tomasz Drwięga committed
173
	type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
174
175
	type MaximumBlockLength = MaximumBlockLength;
	type AvailableBlockRatio = AvailableBlockRatio;
176
	type Version = Version;
177
	type ModuleToIndex = ModuleToIndex;
178
	type AccountData = balances::AccountData<Balance>;
Gavin Wood's avatar
Gavin Wood committed
179
	type OnNewAccount = ();
180
	type OnKilledAccount = ();
181
182
}

Gavin Wood's avatar
Gavin Wood committed
183
184
185
186
187
188
189
impl scheduler::Trait for Runtime {
	type Event = Event;
	type Origin = Origin;
	type Call = Call;
	type MaximumWeight = MaximumBlockWeight;
}

190
parameter_types! {
191
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
192
193
194
195
196
197
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
}

impl babe::Trait for Runtime {
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
198
199
200

	// session module is the trigger
	type EpochChangeTrigger = babe::ExternalTrigger;
201
202
}

Gavin Wood's avatar
Gavin Wood committed
203
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
204
	pub const IndexDeposit: Balance = 10 * DOLLARS;
Gavin Wood's avatar
Gavin Wood committed
205
206
}

Gav Wood's avatar
Gav Wood committed
207
208
impl indices::Trait for Runtime {
	type AccountIndex = AccountIndex;
209
210
	type Currency = Balances;
	type Deposit = IndexDeposit;
Gav Wood's avatar
Gav Wood committed
211
212
213
	type Event = Event;
}

Gavin Wood's avatar
Gavin Wood committed
214
parameter_types! {
215
	pub const ExistentialDeposit: Balance = 100 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
216
217
218
219
220
}

/// Splits fees 80/20 between treasury and block author.
pub type DealWithFees = SplitTwoWays<
	Balance,
221
222
223
	NegativeImbalance<Runtime>,
	_4, Treasury,   		// 4 parts (80%) goes to the treasury.
	_1, ToAuthor<Runtime>,   	// 1 part (20%) goes to the block author.
Gavin Wood's avatar
Gavin Wood committed
224
225
>;

226
impl balances::Trait for Runtime {
Gav's avatar
Gav committed
227
	type Balance = Balance;
228
	type DustRemoval = ();
Gavin Wood's avatar
Gavin Wood committed
229
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
230
	type ExistentialDeposit = ExistentialDeposit;
231
	type AccountStore = System;
232
233
234
235
236
237
}

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

238

239
240
241
impl transaction_payment::Trait for Runtime {
	type Currency = Balances;
	type OnTransactionPayment = DealWithFees;
Gavin Wood's avatar
Gavin Wood committed
242
	type TransactionByteFee = TransactionByteFee;
243
	type WeightToFee = WeightToFee;
244
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
Gav's avatar
Gav committed
245
246
}

247
parameter_types! {
248
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
249
}
250
impl timestamp::Trait for Runtime {
251
	type Moment = u64;
252
	type OnTimestampSet = Babe;
253
	type MinimumPeriod = MinimumPeriod;
254
255
}

Gavin Wood's avatar
Gavin Wood committed
256
parameter_types! {
257
	pub const UncleGenerations: u32 = 0;
Gavin Wood's avatar
Gavin Wood committed
258
259
260
261
}

// TODO: substrate#2986 implement this properly
impl authorship::Trait for Runtime {
262
	type FindAuthor = session::FindAccountFromAuthorIndex<Self, Babe>;
Gavin Wood's avatar
Gavin Wood committed
263
264
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
Gavin Wood's avatar
Gavin Wood committed
265
	type EventHandler = (Staking, ImOnline);
Gavin Wood's avatar
Gavin Wood committed
266
267
}

268
impl_opaque_keys! {
269
	pub struct SessionKeys {
Gavin Wood's avatar
Gavin Wood committed
270
271
272
273
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
		pub parachain_validator: Parachains,
Gavin Wood's avatar
Gavin Wood committed
274
		pub authority_discovery: AuthorityDiscovery,
275
	}
276
277
}

thiolliere's avatar
thiolliere committed
278
279
280
281
parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

282
impl session::Trait for Runtime {
Gav's avatar
Gav committed
283
	type Event = Event;
284
285
	type ValidatorId = AccountId;
	type ValidatorIdOf = staking::StashOf<Self>;
Gavin Wood's avatar
Gavin Wood committed
286
	type ShouldEndSession = Babe;
287
	type NextSessionRotation = Babe;
288
	type SessionManager = session::historical::NoteHistoricalRoot<Self, Staking>;
Gavin Wood's avatar
Gavin Wood committed
289
290
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
thiolliere's avatar
thiolliere committed
291
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
292
293
294
295
}

impl session::historical::Trait for Runtime {
	type FullIdentification = staking::Exposure<AccountId, Balance>;
296
	type FullIdentificationOf = staking::ExposureOf<Runtime>;
297
298
}

299
300
301
// 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))%`.
302
pallet_staking_reward_curve::build! {
thiolliere's avatar
thiolliere committed
303
304
305
	const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
		min_inflation: 0_025_000,
		max_inflation: 0_100_000,
306
307
308
		// 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
309
310
311
312
313
314
		falloff: 0_050_000,
		max_piece_count: 40,
		test_precision: 0_005_000,
	);
}

315
parameter_types! {
Gavin Wood's avatar
Gavin Wood committed
316
	// Six sessions in an era (24 hours).
317
	pub const SessionsPerEra: SessionIndex = 6;
Gavin Wood's avatar
Gavin Wood committed
318
	// 28 eras for unbonding (28 days).
Gavin Wood's avatar
Gavin Wood committed
319
320
	pub const BondingDuration: staking::EraIndex = 28;
	pub const SlashDeferDuration: staking::EraIndex = 28;
thiolliere's avatar
thiolliere committed
321
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
Gavin Wood's avatar
Gavin Wood committed
322
	pub const MaxNominatorRewardedPerValidator: u32 = 64;
323
	// quarter of the last session will be for election.
Gavin Wood's avatar
Gavin Wood committed
324
	pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 16;
325
326
	pub const MaxIterations: u32 = 10;
	pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
327
}
328

Gavin Wood's avatar
Gavin Wood committed
329
330
331
332
333
334
type SlashCancelOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
	collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>
>;

335
impl staking::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
336
	type Currency = Balances;
337
	type UnixTime = Timestamp;
338
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
339
	type RewardRemainder = Treasury;
Gav's avatar
Gav committed
340
	type Event = Event;
341
	type Slash = Treasury;
342
	type Reward = ();
343
344
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
Gavin Wood's avatar
Gavin Wood committed
345
346
	type SlashDeferDuration = SlashDeferDuration;
	// A super-majority of the council can cancel the slash.
Gavin Wood's avatar
Gavin Wood committed
347
	type SlashCancelOrigin = SlashCancelOrigin;
348
	type SessionInterface = Self;
thiolliere's avatar
thiolliere committed
349
	type RewardCurve = RewardCurve;
Gavin Wood's avatar
Gavin Wood committed
350
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
351
352
353
	type NextNewSession = Session;
	type ElectionLookahead = ElectionLookahead;
	type Call = Call;
354
	type UnsignedPriority = StakingUnsignedPriority;
355
	type MaxIterations = MaxIterations;
356
	type MinSolutionScoreBump = MinSolutionScoreBump;
357
358
}

Gavin Wood's avatar
Gavin Wood committed
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
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;
}

impl identity::Trait for Runtime {
	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
379
380
	type ForceOrigin = MoreThanHalfCouncil;
	type RegistrarOrigin = MoreThanHalfCouncil;
Gavin Wood's avatar
Gavin Wood committed
381
382
}

383
parameter_types! {
384
385
	pub const LaunchPeriod: BlockNumber = 28 * DAYS;
	pub const VotingPeriod: BlockNumber = 28 * DAYS;
386
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
387
	pub const MinimumDeposit: Balance = 100 * DOLLARS;
388
389
	pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
Gavin Wood's avatar
Gavin Wood committed
390
391
	// One cent: $10,000 / MB
	pub const PreimageByteDeposit: Balance = 1 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
392
	pub const InstantAllowed: bool = true;
393
	pub const MaxVotes: u32 = 100;
394
395
}

396
397
398
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
399
	type Currency = Balances;
400
401
402
403
	type EnactmentPeriod = EnactmentPeriod;
	type LaunchPeriod = LaunchPeriod;
	type VotingPeriod = VotingPeriod;
	type MinimumDeposit = MinimumDeposit;
404
	/// A straight majority of the council can decide what their next motion is.
Gavin Wood's avatar
Gavin Wood committed
405
406
407
408
	type ExternalOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>,
		system::EnsureRoot<AccountId>,
	>;
409
	/// A 60% super-majority can have the next scheduled referendum be a straight majority-carries vote.
Gavin Wood's avatar
Gavin Wood committed
410
411
412
413
	type ExternalMajorityOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>,
		system::EnsureRoot<AccountId>,
	>;
414
415
	/// A unanimous council can have the next scheduled referendum be a straight default-carries
	/// (NTB) vote.
Gavin Wood's avatar
Gavin Wood committed
416
417
418
419
	type ExternalDefaultOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>,
		system::EnsureRoot<AccountId>,
	>;
420
421
	/// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote
	/// be tabled immediately and with a shorter voting/enactment period.
Gavin Wood's avatar
Gavin Wood committed
422
423
424
425
426
427
428
429
	type FastTrackOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>,
		system::EnsureRoot<AccountId>,
	>;
	type InstantOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>,
		system::EnsureRoot<AccountId>,
	>;
430
431
	type InstantAllowed = InstantAllowed;
	type FastTrackVotingPeriod = FastTrackVotingPeriod;
432
	// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
Gavin Wood's avatar
Gavin Wood committed
433
434
435
436
	type CancellationOrigin = system::EnsureOneOf<AccountId,
		collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
		system::EnsureRoot<AccountId>,
	>;
437
438
439
	// 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.
	type VetoOrigin = collective::EnsureMember<AccountId, TechnicalCollective>;
440
	type CooloffPeriod = CooloffPeriod;
Gavin Wood's avatar
Gavin Wood committed
441
	type PreimageByteDeposit = PreimageByteDeposit;
Gavin Wood's avatar
Gavin Wood committed
442
	type OperationalPreimageOrigin = collective::EnsureMember<AccountId, CouncilCollective>;
Gavin Wood's avatar
Gavin Wood committed
443
	type Slash = Treasury;
Gavin Wood's avatar
Gavin Wood committed
444
	type Scheduler = Scheduler;
445
	type MaxVotes = MaxVotes;
446
}
447

448
449
parameter_types! {
	pub const CouncilMotionDuration: BlockNumber = 7 * DAYS;
450
	pub const CouncilMaxProposals: u32 = 100;
451
452
}

453
454
type CouncilCollective = collective::Instance1;
impl collective::Trait<CouncilCollective> for Runtime {
455
456
457
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
458
	type MotionDuration = CouncilMotionDuration;
459
	type MaxProposals = CouncilMaxProposals;
460
461
}

Gavin Wood's avatar
Gavin Wood committed
462
parameter_types! {
463
464
	pub const CandidacyBond: Balance = 100 * DOLLARS;
	pub const VotingBond: Balance = 5 * DOLLARS;
465
466
467
	/// Weekly council elections initially, later monthly.
	pub const TermDuration: BlockNumber = 7 * DAYS;
	/// 13 members initially, to be increased to 23 eventually.
468
	pub const DesiredMembers: u32 = 13;
469
	pub const DesiredRunnersUp: u32 = 20;
470
	pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
471
}
472
// Make sure that there are no more than MAX_MEMBERS members elected via phragmen.
473
const_assert!(DesiredMembers::get() <= collective::MAX_MEMBERS);
474
475

impl elections_phragmen::Trait for Runtime {
476
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
477
	type ModuleId = ElectionsPhragmenModuleId;
478
479
	type Currency = Balances;
	type ChangeMembers = Council;
480
	type InitializeMembers = Council;
481
	type CurrencyToVote = CurrencyToVoteHandler<Self>;
Gavin Wood's avatar
Gavin Wood committed
482
483
	type CandidacyBond = CandidacyBond;
	type VotingBond = VotingBond;
484
485
486
	type LoserCandidate = Treasury;
	type BadReport = Treasury;
	type KickedMember = Treasury;
Gavin Wood's avatar
Gavin Wood committed
487
488
489
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
	type TermDuration = TermDuration;
490
491
}

492
493
parameter_types! {
	pub const TechnicalMotionDuration: BlockNumber = 7 * DAYS;
494
	pub const TechnicalMaxProposals: u32 = 100;
495
496
}

497
498
type TechnicalCollective = collective::Instance2;
impl collective::Trait<TechnicalCollective> for Runtime {
499
500
501
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
502
	type MotionDuration = TechnicalMotionDuration;
503
	type MaxProposals = TechnicalMaxProposals;
504
505
}

506
507
impl membership::Trait<membership::Instance1> for Runtime {
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
508
509
510
511
512
	type AddOrigin = MoreThanHalfCouncil;
	type RemoveOrigin = MoreThanHalfCouncil;
	type SwapOrigin = MoreThanHalfCouncil;
	type ResetOrigin = MoreThanHalfCouncil;
	type PrimeOrigin = MoreThanHalfCouncil;
513
514
515
516
	type MembershipInitialized = TechnicalCommittee;
	type MembershipChanged = TechnicalCommittee;
}

Gavin Wood's avatar
Gavin Wood committed
517
518
parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
519
520
521
	pub const ProposalBondMinimum: Balance = 100 * DOLLARS;
	pub const SpendPeriod: BlockNumber = 24 * DAYS;
	pub const Burn: Permill = Permill::from_percent(1);
522
	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
Gavin Wood's avatar
Gavin Wood committed
523
524
525
526
527

	pub const TipCountdown: BlockNumber = 1 * DAYS;
	pub const TipFindersFee: Percent = Percent::from_percent(20);
	pub const TipReportDepositBase: Balance = 1 * DOLLARS;
	pub const TipReportDepositPerByte: Balance = 1 * CENTS;
Gavin Wood's avatar
Gavin Wood committed
528
529
}

Gavin Wood's avatar
Gavin Wood committed
530
531
532
type ApproveOrigin = EnsureOneOf<
	AccountId,
	EnsureRoot<AccountId>,
Shawn Tabrizi's avatar
Shawn Tabrizi committed
533
	collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>
Gavin Wood's avatar
Gavin Wood committed
534
535
>;

536
impl treasury::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
537
	type ModuleId = TreasuryModuleId;
Gavin Wood's avatar
Gavin Wood committed
538
	type Currency = Balances;
Gavin Wood's avatar
Gavin Wood committed
539
540
	type ApproveOrigin = ApproveOrigin;
	type RejectOrigin = MoreThanHalfCouncil;
Gavin Wood's avatar
Gavin Wood committed
541
542
543
544
545
	type Tippers = ElectionsPhragmen;
	type TipCountdown = TipCountdown;
	type TipFindersFee = TipFindersFee;
	type TipReportDepositBase = TipReportDepositBase;
	type TipReportDepositPerByte = TipReportDepositPerByte;
546
	type Event = Event;
547
	type ProposalRejection = Treasury;
Gavin Wood's avatar
Gavin Wood committed
548
549
550
551
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
552
}
553

554
parameter_types! {
555
	pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
556
557
}

558
559
560
561
impl offences::Trait for Runtime {
	type Event = Event;
	type IdentificationTuple = session::historical::IdentificationTuple<Self>;
	type OnOffenceHandler = Staking;
562
	type WeightSoftLimit = OffencesWeightSoftLimit;
563
564
}

Gavin Wood's avatar
Gavin Wood committed
565
566
impl authority_discovery::Trait for Runtime {}

567
568
569
570
parameter_types! {
	pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS as _;
}

571
572
573
574
575
parameter_types! {
	pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

576
impl im_online::Trait for Runtime {
thiolliere's avatar
thiolliere committed
577
	type AuthorityId = ImOnlineId;
578
	type Event = Event;
579
	type SessionDuration = SessionDuration;
Gavin Wood's avatar
Gavin Wood committed
580
	type ReportUnresponsiveness = Offences;
581
	type UnsignedPriority = ImOnlineUnsignedPriority;
582
583
}

584
585
impl grandpa::Trait for Runtime {
	type Event = Event;
586
587
588
589
590
591
592
593
594
595
	type Call = Call;

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

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

Gavin Wood's avatar
Gavin Wood committed
596
597
	type KeyOwnerProofSystem = Historical;

598
599
600
601
602
603
	type HandleEquivocation = grandpa::EquivocationHandler<
		Self::KeyOwnerIdentification,
		primitives::fisherman::FishermanAppCrypto,
		Runtime,
		Offences,
	>;
604
605
}

Gavin Wood's avatar
Gavin Wood committed
606
parameter_types! {
607
608
	pub WindowSize: BlockNumber = finality_tracker::DEFAULT_WINDOW_SIZE.into();
	pub ReportLatency: BlockNumber = finality_tracker::DEFAULT_REPORT_LATENCY.into();
Gavin Wood's avatar
Gavin Wood committed
609
610
611
}

impl finality_tracker::Trait for Runtime {
612
	type OnFinalizationStalled = ();
Gavin Wood's avatar
Gavin Wood committed
613
614
615
616
	type WindowSize = WindowSize;
	type ReportLatency = ReportLatency;
}

617
618
619
620
parameter_types! {
	pub const AttestationPeriod: BlockNumber = 50;
}

621
622
623
impl attestations::Trait for Runtime {
	type AttestationPeriod = AttestationPeriod;
	type ValidatorIdentities = parachains::ValidatorIdentities<Runtime>;
624
	type RewardAttestation = Staking;
625
626
}

627
628
629
parameter_types! {
	pub const MaxCodeSize: u32 = 10 * 1024 * 1024; // 10 MB
	pub const MaxHeadDataSize: u32 = 20 * 1024; // 20 KB
630
631
632
633

	pub const ValidationUpgradeFrequency: BlockNumber = 7 * DAYS;
	pub const ValidationUpgradeDelay: BlockNumber = 1 * DAYS;
	pub const SlashPeriod: BlockNumber = 28 * DAYS;
634
635
}

636
impl parachains::Trait for Runtime {
637
	type AuthorityId = primitives::fisherman::FishermanAppCrypto;
638
639
	type Origin = Origin;
	type Call = Call;
640
	type ParachainCurrency = Balances;
641
	type BlockNumberConversion = sp_runtime::traits::Identity;
642
	type Randomness = RandomnessCollectiveFlip;
643
644
	type ActiveParachains = Registrar;
	type Registrar = Registrar;
645
646
	type MaxCodeSize = MaxCodeSize;
	type MaxHeadDataSize = MaxHeadDataSize;
647
648
649
650
651

	type ValidationUpgradeFrequency = ValidationUpgradeFrequency;
	type ValidationUpgradeDelay = ValidationUpgradeDelay;
	type SlashPeriod = SlashPeriod;

652
	type Proof = sp_session::MembershipProof;
653
654
655
	type KeyOwnerProofSystem = session::historical::Module<Self>;
	type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple;
	type ReportOffence = Offences;
656
	type BlockHashConversion = sp_runtime::traits::Identity;
657
658
}

659
660
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
661
662
663
664
665
666
667
impl<LocalCall> system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
	Call: From<LocalCall>,
{
	fn create_transaction<C: system::offchain::AppCrypto<Self::Public, Self::Signature>>(
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
668
669
		nonce: <Runtime as system::Trait>::Index,
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
670
		// take the biggest period possible.
671
672
673
674
675
676
677
		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>()
678
679
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
680
681
682
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
683
684
			system::CheckSpecVersion::<Runtime>::new(),
			system::CheckTxVersion::<Runtime>::new(),
685
			system::CheckGenesis::<Runtime>::new(),
686
			system::CheckMortality::<Runtime>::from(generic::Era::mortal(period, current_block)),
687
688
689
690
691
			system::CheckNonce::<Runtime>::from(nonce),
			system::CheckWeight::<Runtime>::new(),
			transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
			registrar::LimitParathreadCommits::<Runtime>::new(),
			parachains::ValidateDoubleVoteReports::<Runtime>::new(),
692
			grandpa::ValidateEquivocationReport::<Runtime>::new(),
693
			claims::PrevalidateAttests::<Runtime>::new(),
694
695
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
696
			debug::warn!("Unable to create signed payload: {:?}", e);
697
		}).ok()?;
698
699
700
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
701
702
703
		let (call, extra, _) = raw_payload.deconstruct();
		Some((call, (account, signature, extra)))
	}
704
705
}

706
707
708
709
710
impl system::offchain::SigningTypes for Runtime {
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

Gavin Wood's avatar
Gavin Wood committed
711
impl<C> system::offchain::SendTransactionTypes<C> for Runtime where Call: From<C> {
712
	type Extrinsic = UncheckedExtrinsic;
Gavin Wood's avatar
Gavin Wood committed
713
	type OverarchingCall = Call;
714
715
}

716
717
718
719
720
721
722
723
724
725
726
727
728
729
parameter_types! {
	pub const ParathreadDeposit: Balance = 500 * DOLLARS;
	pub const QueueSize: usize = 2;
	pub const MaxRetries: u32 = 3;
}

impl registrar::Trait for Runtime {
	type Event = Event;
	type Origin = Origin;
	type Currency = Balances;
	type ParathreadDeposit = ParathreadDeposit;
	type SwapAux = Slots;
	type QueueSize = QueueSize;
	type MaxRetries = MaxRetries;
730
}
731

Gavin Wood's avatar
Gavin Wood committed
732
parameter_types! {
733
	pub const LeasePeriod: BlockNumber = 100_000;
Gavin Wood's avatar
Gavin Wood committed
734
735
736
737
738
	pub const EndingPeriod: BlockNumber = 1000;
}

impl slots::Trait for Runtime {
	type Event = Event;
739
740
	type Currency = Balances;
	type Parachains = Registrar;
Gavin Wood's avatar
Gavin Wood committed
741
	type EndingPeriod = EndingPeriod;
Gavin Wood's avatar
Gavin Wood committed
742
	type LeasePeriod = LeasePeriod;
743
	type Randomness = RandomnessCollectiveFlip;
Gavin Wood's avatar
Gavin Wood committed
744
745
}

Gavin Wood's avatar
Gavin Wood committed
746
parameter_types! {
747
	pub Prefix: &'static [u8] = b"Pay DOTs to the Polkadot account:";
748
749
750
751
}

impl claims::Trait for Runtime {
	type Event = Event;
Gavin Wood's avatar
Gavin Wood committed
752
	type VestingSchedule = Vesting;
753
	type Prefix = Prefix;
754
755
	/// At least 3/4 of the council must agree to a claim move before it can happen.
	type MoveClaimOrigin = collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
756
757
}

758
759
760
761
parameter_types! {
	pub const MinVestedTransfer: Balance = 100 * DOLLARS;
}

Gavin Wood's avatar
Gavin Wood committed
762
763
764
765
impl vesting::Trait for Runtime {
	type Event = Event;
	type Currency = Balances;
	type BlockNumberToBalance = ConvertInto;
766
	type MinVestedTransfer = MinVestedTransfer;
Gavin Wood's avatar
Gavin Wood committed
767
768
}

769
770
771
772
773
impl utility::Trait for Runtime {
	type Event = Event;
	type Call = Call;
}

Gavin Wood's avatar
Gavin Wood committed
774
parameter_types! {
775
776
	// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
	pub const DepositBase: Balance = deposit(1, 88);
Gavin Wood's avatar
Gavin Wood committed
777
	// Additional storage item size of 32 bytes.
778
	pub const DepositFactor: Balance = deposit(0, 32);
Gavin Wood's avatar
Gavin Wood committed
779
780
781
	pub const MaxSignatories: u16 = 100;
}

782
impl multisig::Trait for Runtime {
Gavin Wood's avatar
Gavin Wood committed
783
784
785
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
786
787
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
Gavin Wood's avatar
Gavin Wood committed
788
789
790
	type MaxSignatories = MaxSignatories;
}

791
792
impl sudo::Trait for Runtime {
	type Event = Event;
793
	type Call = Call;
794
795
}

796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
parameter_types! {
	// One storage item; key size 32, value size 8; .
	pub const ProxyDepositBase: Balance = deposit(1, 8);
	// Additional storage item size of 33 bytes.
	pub const ProxyDepositFactor: Balance = deposit(0, 33);
	pub const MaxProxies: u16 = 32;
}

/// The type used to represent the kinds of proxying allowed.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)]
pub enum ProxyType {
	Any,
	NonTransfer,
	Governance,
	Staking,
811
	SudoBalances,
Chevdor's avatar
Chevdor committed
812
	IdentityJudgement,
813
814
815
816
817
818
}
impl Default for ProxyType { fn default() -> Self { Self::Any } }
impl InstanceFilter<Call> for ProxyType {
	fn filter(&self, c: &Call) -> bool {
		match self {
			ProxyType::Any => true,
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
			ProxyType::NonTransfer => matches!(c,
				Call::System(..) |
				Call::Scheduler(..) |
				Call::Babe(..) |
				Call::Timestamp(..) |
				Call::Indices(indices::Call::claim(..)) |
				Call::Indices(indices::Call::free(..)) |
				Call::Indices(indices::Call::freeze(..)) |
				// Specifically omitting Indices `transfer`, `force_transfer`
				// Specifically omitting the entire Balances pallet
				Call::Authorship(..) |
				Call::Staking(..) |
				Call::Offences(..) |
				Call::Session(..) |
				Call::FinalityTracker(..) |
				Call::Grandpa(..) |
				Call::ImOnline(..) |
				Call::AuthorityDiscovery(..) |
				Call::Democracy(..) |
				Call::Council(..) |
				Call::TechnicalCommittee(..) |
				Call::ElectionsPhragmen(..) |
				Call::TechnicalMembership(..) |
				Call::Treasury(..) |
				Call::Parachains(..) |
				Call::Attestations(..) |
				Call::Slots(..) |
				Call::Registrar(..) |
				Call::Claims(..) |
				Call::Vesting(vesting::Call::vest(..)) |
				Call::Vesting(vesting::Call::vest_other(..)) |
				// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
				Call::Utility(..) |
				// Specifically omitting Sudo pallet
				Call::Identity(..) |
				Call::Proxy(..) |
				Call::Multisig(..)
856
857
858
			),
			ProxyType::Governance => matches!(c,
				Call::Democracy(..) | Call::Council(..) | Call::TechnicalCommittee(..)
Gavin Wood's avatar
Gavin Wood committed
859
					| Call::ElectionsPhragmen(..) | Call::Treasury(..) | Call::Utility(..)
860
861
			),
			ProxyType::Staking => matches!(c,
Gavin Wood's avatar
Gavin Wood committed
862
				Call::Staking(..) | Call::Utility(utility::Call::batch(..)) | Call::Utility(..)
863
			),
864
865
			ProxyType::SudoBalances => match c {
				Call::Sudo(sudo::Call::sudo(ref x)) => matches!(x.as_ref(), &Call::Balances(..)),
Gavin Wood's avatar
Gavin Wood committed
866
				Call::Utility(..) => true,
867
868
				_ => false,
			},
Chevdor's avatar
Chevdor committed
869
870
871
872
			ProxyType::IdentityJudgement => matches!(c,
				Call::Identity(identity::Call::provide_judgement(..))
				| Call::Utility(utility::Call::batch(..))
			)
873
874
875
876
877
878
879
880
881
		}
	}
	fn is_superset(&self, o: &Self) -> bool {
		match (self, o) {
			(x, y) if x == y => true,
			(ProxyType::Any, _) => true,
			(_, ProxyType::Any) => false,
			(ProxyType::NonTransfer, _) => true,
			_ => false,
882
883
884
885
886
887
888
889
890
891
892
893
894
895
		}
	}
}

impl proxy::Trait for Runtime {
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
	type ProxyType = ProxyType;
	type ProxyDepositBase = ProxyDepositBase;
	type ProxyDepositFactor = ProxyDepositFactor;
	type MaxProxies = MaxProxies;
}

Gavin Wood's avatar
Gavin Wood committed
896
construct_runtime! {
897
	pub enum Runtime where
898
		Block = Block,
899
		NodeBlock = primitives::Block,
900
		UncheckedExtrinsic = UncheckedExtrinsic
901
	{
902
		// Basic stuff; balances is uncallable initially.
Gavin Wood's avatar
Gavin Wood committed
903
		System: system::{Module, Call, Storage, Config, Event<T>},
Ashley's avatar
Ashley committed
904
		RandomnessCollectiveFlip: randomness_collective_flip::{Module, Storage},
Gavin Wood's avatar
Gavin Wood committed
905
		Scheduler: scheduler::{Module, Call, Storage, Event<T>},
906
907

		// Must be before session.