lib.rs 50.9 KB
Newer Older
ddorgan's avatar
ddorgan committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// 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/>.

//! The Polkadot runtime. This can be compiled with `#[no_std]`, ready for Wasm.

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

Albrecht's avatar
Albrecht committed
23
use pallet_transaction_payment::CurrencyAdapter;
ddorgan's avatar
ddorgan committed
24
use sp_std::prelude::*;
Sergey Pepyakin's avatar
Sergey Pepyakin committed
25
use sp_std::collections::btree_map::BTreeMap;
26
use parity_scale_codec::{Encode, Decode};
27
use primitives::v1::{
28
	AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
29
	CoreState, GroupRotationInfo, Hash, Id as ParaId, Moment, Nonce, OccupiedCoreAssumption,
30
	PersistedValidationData, Signature, ValidationCode, ValidatorId, ValidatorIndex,
31
	InboundDownwardMessage, InboundHrmpMessage, SessionInfo,
ddorgan's avatar
ddorgan committed
32
};
33
use runtime_common::{
34
	paras_sudo_wrapper, paras_registrar, xcm_sender, slots, crowdloan, auctions,
35
36
	SlowAdjustingFeeUpdate, CurrencyToVote,
	impls::ToAuthor,
37
38
	BlockHashCount, BlockWeights, BlockLength, RocksDbWeight,
	OffchainSolutionWeightLimit, OffchainSolutionLengthLimit,
ddorgan's avatar
ddorgan committed
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, Xcm, Junction::Parachain};
use xcm::v0::MultiAsset::{self, AllConcreteFungible};
58
59
60
61
use xcm_executor::XcmExecutor;
use xcm_builder::{
	AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter,
	ChildParachainAsNative, SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter, IsConcrete,
62
63
	FixedWeightBounds, TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
	IsChildSystemParachain, UsingComponents, SignedToAccountId32,
64
};
65

ddorgan's avatar
ddorgan committed
66
67
use sp_runtime::{
	create_runtime_str, generic, impl_opaque_keys,
68
	ApplyExtrinsicResult, KeyTypeId, Perbill, curve::PiecewiseLinear,
Gavin Wood's avatar
Gavin Wood committed
69
	transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority},
ddorgan's avatar
ddorgan committed
70
	traits::{
71
		BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, AccountIdLookup,
Gavin Wood's avatar
Gavin Wood committed
72
		Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
ddorgan's avatar
ddorgan committed
73
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};
ddorgan's avatar
ddorgan committed
79
#[cfg(any(feature = "std", test))]
80
use sp_version::NativeVersion;
ddorgan's avatar
ddorgan committed
81
82
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
83
use frame_support::{
84
	parameter_types, construct_runtime, RuntimeDebug, PalletId,
85
	traits::{KeyOwnerProofSystem, Filter, InstanceFilter, All, MaxEncodedLen},
86
	weights::Weight,
87
};
88
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
ddorgan's avatar
ddorgan committed
89
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
90
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
91
use pallet_session::historical as session_historical;
92
use frame_system::{EnsureRoot};
93
94
use beefy_primitives::ecdsa::AuthorityId as BeefyId;
use pallet_mmr_primitives as mmr;
ddorgan's avatar
ddorgan committed
95
96

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

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

107
108
109
// Weights used in the runtime
mod weights;

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

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

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

131
132
133
134
135
136
137
/// 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
	};

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

147
/// Allow everything.
148
149
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
150
151
	fn filter(_: &Call) -> bool {
		true
ddorgan's avatar
ddorgan committed
152
153
154
155
156
	}
}

parameter_types! {
	pub const Version: RuntimeVersion = VERSION;
157
	pub const SS58Prefix: u8 = 42;
ddorgan's avatar
ddorgan committed
158
159
}

160
impl frame_system::Config for Runtime {
161
	type BaseCallFilter = BaseFilter;
162
163
	type BlockWeights = BlockWeights;
	type BlockLength = BlockLength;
ddorgan's avatar
ddorgan committed
164
165
166
167
168
169
170
	type Origin = Origin;
	type Call = Call;
	type Index = Nonce;
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
171
	type Lookup = AccountIdLookup<AccountId, ()>;
ddorgan's avatar
ddorgan committed
172
173
174
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
	type Event = Event;
	type BlockHashCount = BlockHashCount;
175
	type DbWeight = RocksDbWeight;
ddorgan's avatar
ddorgan committed
176
	type Version = Version;
177
	type PalletInfo = PalletInfo;
178
	type AccountData = pallet_balances::AccountData<Balance>;
ddorgan's avatar
ddorgan committed
179
180
	type OnNewAccount = ();
	type OnKilledAccount = ();
181
	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
182
	type SS58Prefix = SS58Prefix;
183
	type OnSetCode = ();
ddorgan's avatar
ddorgan committed
184
185
}

186
parameter_types! {
187
188
	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
		BlockWeights::get().max_block;
189
190
191
	pub const MaxScheduledPerBlock: u32 = 50;
}

192
impl pallet_scheduler::Config for Runtime {
ddorgan's avatar
ddorgan committed
193
194
	type Event = Event;
	type Origin = Origin;
195
	type PalletsOrigin = OriginCaller;
ddorgan's avatar
ddorgan committed
196
	type Call = Call;
197
	type MaximumWeight = MaximumSchedulerWeight;
198
	type ScheduleOrigin = EnsureRoot<AccountId>;
199
	type MaxScheduledPerBlock = MaxScheduledPerBlock;
200
	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
201
202
203
}

parameter_types! {
204
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
ddorgan's avatar
ddorgan committed
205
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
206
207
	pub const ReportLongevity: u64 =
		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
ddorgan's avatar
ddorgan committed
208
209
}

210
impl pallet_babe::Config for Runtime {
ddorgan's avatar
ddorgan committed
211
212
213
214
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;

	// session module is the trigger
215
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
216
217
218
219
220

	type KeyOwnerProofSystem = Historical;

	type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
221
		pallet_babe::AuthorityId,
222
223
224
225
	)>>::Proof;

	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
226
		pallet_babe::AuthorityId,
227
228
229
	)>>::IdentificationTuple;

	type HandleEquivocation =
230
		pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
231
232

	type WeightInfo = ();
ddorgan's avatar
ddorgan committed
233
234
235
}

parameter_types! {
236
	pub const IndexDeposit: Balance = 100 * CENTS;
ddorgan's avatar
ddorgan committed
237
238
}

239
impl pallet_indices::Config for Runtime {
ddorgan's avatar
ddorgan committed
240
241
242
243
	type AccountIndex = AccountIndex;
	type Currency = Balances;
	type Deposit = IndexDeposit;
	type Event = Event;
244
	type WeightInfo = weights::pallet_indices::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
245
246
247
248
}

parameter_types! {
	pub const ExistentialDeposit: Balance = 1 * CENTS;
249
	pub const MaxLocks: u32 = 50;
ddorgan's avatar
ddorgan committed
250
251
}

252
impl pallet_balances::Config for Runtime {
ddorgan's avatar
ddorgan committed
253
254
255
256
257
	type Balance = Balance;
	type DustRemoval = ();
	type Event = Event;
	type ExistentialDeposit = ExistentialDeposit;
	type AccountStore = System;
258
	type MaxLocks = MaxLocks;
259
	type WeightInfo = weights::pallet_balances::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
260
261
262
263
264
265
}

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

266
impl pallet_transaction_payment::Config for Runtime {
Albrecht's avatar
Albrecht committed
267
	type OnChargeTransaction = CurrencyAdapter<Balances, ToAuthor<Runtime>>;
ddorgan's avatar
ddorgan committed
268
269
	type TransactionByteFee = TransactionByteFee;
	type WeightToFee = WeightToFee;
270
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
ddorgan's avatar
ddorgan committed
271
272
273
274
275
}

parameter_types! {
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
}
276
impl pallet_timestamp::Config for Runtime {
ddorgan's avatar
ddorgan committed
277
278
279
	type Moment = u64;
	type OnTimestampSet = Babe;
	type MinimumPeriod = MinimumPeriod;
280
	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
281
282
283
284
285
286
}

parameter_types! {
	pub const UncleGenerations: u32 = 0;
}

287
impl pallet_authorship::Config for Runtime {
288
	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
ddorgan's avatar
ddorgan committed
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
	type EventHandler = (Staking, ImOnline);
}

parameter_types! {
	pub const Period: BlockNumber = 10 * MINUTES;
	pub const Offset: BlockNumber = 0;
}

impl_opaque_keys! {
	pub struct SessionKeys {
		pub grandpa: Grandpa,
		pub babe: Babe,
		pub im_online: ImOnline,
304
305
		pub para_validator: ParasInitializer,
		pub para_assignment: ParasSessionInfo,
ddorgan's avatar
ddorgan committed
306
307
308
309
310
311
312
313
		pub authority_discovery: AuthorityDiscovery,
	}
}

parameter_types! {
	pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

314
impl pallet_session::Config for Runtime {
ddorgan's avatar
ddorgan committed
315
316
	type Event = Event;
	type ValidatorId = AccountId;
317
	type ValidatorIdOf = pallet_staking::StashOf<Self>;
ddorgan's avatar
ddorgan committed
318
319
	type ShouldEndSession = Babe;
	type NextSessionRotation = Babe;
320
	type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
ddorgan's avatar
ddorgan committed
321
322
323
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
324
	type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
325
326
}

327
impl pallet_session::historical::Config for Runtime {
328
329
	type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
	type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
ddorgan's avatar
ddorgan committed
330
331
}

332
333
334
parameter_types! {
	// no signed phase for now, just unsigned.
	pub const SignedPhase: u32 = 0;
335
	pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
336

337
	// fallback: run election on-chain.
338
	pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy =
339
		pallet_election_provider_multi_phase::FallbackStrategy::OnChain;
340

341
	pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(5u32, 10_000);
342
343
344

	// miner configs
	pub const MinerMaxIterations: u32 = 10;
345
	pub OffchainRepeat: BlockNumber = 5;
346
347
}

348
349
sp_npos_elections::generate_solution_type!(
	#[compact]
350
351
352
353
354
	pub struct NposCompactSolution16::<
		VoterIndex = u32,
		TargetIndex = u16,
		Accuracy = sp_runtime::PerU16,
	>(16)
355
356
);

357
358
359
360
361
impl pallet_election_provider_multi_phase::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
	type SignedPhase = SignedPhase;
	type UnsignedPhase = UnsignedPhase;
362
	type SolutionImprovementThreshold = SolutionImprovementThreshold;
363
	type MinerMaxIterations = MinerMaxIterations;
364
	type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
365
	type MinerMaxLength = OffchainSolutionLengthLimit;
366
	type OffchainRepeat = OffchainRepeat;
367
	type MinerTxPriority = NposSolutionPriority;
368
369
	type DataProvider = Staking;
	type OnChainAccuracy = Perbill;
370
	type CompactSolution = NposCompactSolution16;
371
372
	type Fallback = Fallback;
	type BenchmarkingConfig = ();
373
	type ForceOrigin = EnsureRoot<AccountId>;
374
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
375
376
}

ddorgan's avatar
ddorgan committed
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
pallet_staking_reward_curve::build! {
	const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
		min_inflation: 0_025_000,
		max_inflation: 0_100_000,
		ideal_stake: 0_500_000,
		falloff: 0_050_000,
		max_piece_count: 40,
		test_precision: 0_005_000,
	);
}

parameter_types! {
	// Six sessions in an era (6 hours).
	pub const SessionsPerEra: SessionIndex = 6;
	// 28 eras for unbonding (7 days).
392
	pub const BondingDuration: pallet_staking::EraIndex = 28;
393
	// 27 eras in which slashes can be cancelled (slightly less than 7 days).
394
	pub const SlashDeferDuration: pallet_staking::EraIndex = 27;
ddorgan's avatar
ddorgan committed
395
396
397
398
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
	pub const MaxNominatorRewardedPerValidator: u32 = 64;
}

399
impl pallet_staking::Config for Runtime {
400
	const MAX_NOMINATIONS: u32 = <NposCompactSolution16 as sp_npos_elections::CompactSolution>::LIMIT as u32;
ddorgan's avatar
ddorgan committed
401
402
	type Currency = Balances;
	type UnixTime = Timestamp;
403
	type CurrencyToVote = CurrencyToVote;
ddorgan's avatar
ddorgan committed
404
405
406
407
408
409
410
411
	type RewardRemainder = ();
	type Event = Event;
	type Slash = ();
	type Reward = ();
	type SessionsPerEra = SessionsPerEra;
	type BondingDuration = BondingDuration;
	type SlashDeferDuration = SlashDeferDuration;
	// A majority of the council can cancel the slash.
412
	type SlashCancelOrigin = EnsureRoot<AccountId>;
ddorgan's avatar
ddorgan committed
413
	type SessionInterface = Self;
Kian Paimani's avatar
Kian Paimani committed
414
	type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
ddorgan's avatar
ddorgan committed
415
416
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
	type NextNewSession = Session;
417
	type ElectionProvider = ElectionProviderMultiPhase;
418
	type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
419
420
421
422
423
424
}

parameter_types! {
	pub const LaunchPeriod: BlockNumber = 7 * DAYS;
	pub const VotingPeriod: BlockNumber = 7 * DAYS;
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
425
	pub const MinimumDeposit: Balance = 100 * CENTS;
ddorgan's avatar
ddorgan committed
426
427
428
429
430
431
432
	pub const EnactmentPeriod: BlockNumber = 8 * DAYS;
	pub const CooloffPeriod: BlockNumber = 7 * DAYS;
	// One cent: $10,000 / MB
	pub const PreimageByteDeposit: Balance = 10 * MILLICENTS;
	pub const InstantAllowed: bool = true;
}

433
impl pallet_offences::Config for Runtime {
ddorgan's avatar
ddorgan committed
434
	type Event = Event;
435
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
ddorgan's avatar
ddorgan committed
436
437
438
	type OnOffenceHandler = Staking;
}

439
impl pallet_authority_discovery::Config for Runtime {}
ddorgan's avatar
ddorgan committed
440
441

parameter_types! {
442
	pub const NposSolutionPriority: TransactionPriority = TransactionPriority::max_value() / 2;
ddorgan's avatar
ddorgan committed
443
444
445
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

446
impl pallet_im_online::Config for Runtime {
ddorgan's avatar
ddorgan committed
447
448
	type AuthorityId = ImOnlineId;
	type Event = Event;
449
	type ValidatorSet = Historical;
450
	type NextSessionRotation = Babe;
ddorgan's avatar
ddorgan committed
451
	type ReportUnresponsiveness = Offences;
452
	type UnsignedPriority = ImOnlineUnsignedPriority;
453
	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
454
455
}

456
impl pallet_grandpa::Config for Runtime {
ddorgan's avatar
ddorgan committed
457
	type Event = Event;
458
459
460
461
462
463
464
465
466
467
468
469
	type Call = Call;

	type KeyOwnerProofSystem = Historical;

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

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

470
471
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
472
473

	type WeightInfo = ();
ddorgan's avatar
ddorgan committed
474
475
}

476
477
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
478
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
479
480
	Call: From<LocalCall>,
{
481
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
482
483
484
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
485
		nonce: <Runtime as frame_system::Config>::Index,
486
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
487
		use sp_runtime::traits::StaticLookup;
488
		// take the biggest period possible.
489
490
491
492
493
494
495
		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>()
496
497
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
498
499
500
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
501
502
503
504
505
506
507
			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),
508
509
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
510
			log::warn!("Unable to create signed payload: {:?}", e);
511
		}).ok()?;
512
513
514
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
515
		let (call, extra, _) = raw_payload.deconstruct();
516
517
		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
		Some((call, (address, signature, extra)))
518
	}
ddorgan's avatar
ddorgan committed
519
520
}

521
impl frame_system::offchain::SigningTypes for Runtime {
522
523
524
525
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

526
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where
527
528
529
530
531
532
	Call: From<C>,
{
	type OverarchingCall = Call;
	type Extrinsic = UncheckedExtrinsic;
}

ddorgan's avatar
ddorgan committed
533
534
parameter_types! {
	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
535
	pub const BasicDeposit: Balance = 1000 * CENTS;       // 258 bytes on-chain
ddorgan's avatar
ddorgan committed
536
	pub const FieldDeposit: Balance = 250 * CENTS;        // 66 bytes on-chain
537
	pub const SubAccountDeposit: Balance = 200 * CENTS;   // 53 bytes on-chain
ddorgan's avatar
ddorgan committed
538
539
	pub const MaxSubAccounts: u32 = 100;
	pub const MaxAdditionalFields: u32 = 100;
540
	pub const MaxRegistrars: u32 = 20;
ddorgan's avatar
ddorgan committed
541
542
}

543
impl pallet_identity::Config for Runtime {
ddorgan's avatar
ddorgan committed
544
545
546
547
548
549
550
551
	type Event = Event;
	type Currency = Balances;
	type Slashed = ();
	type BasicDeposit = BasicDeposit;
	type FieldDeposit = FieldDeposit;
	type SubAccountDeposit = SubAccountDeposit;
	type MaxSubAccounts = MaxSubAccounts;
	type MaxAdditionalFields = MaxAdditionalFields;
552
	type MaxRegistrars = MaxRegistrars;
553
554
	type RegistrarOrigin = frame_system::EnsureRoot<AccountId>;
	type ForceOrigin = frame_system::EnsureRoot<AccountId>;
555
	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
556
557
}

558
impl pallet_utility::Config for Runtime {
559
560
	type Event = Event;
	type Call = Call;
561
	type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
562
563
}

ddorgan's avatar
ddorgan committed
564
parameter_types! {
565
566
	// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
	pub const DepositBase: Balance = deposit(1, 88);
ddorgan's avatar
ddorgan committed
567
	// Additional storage item size of 32 bytes.
568
	pub const DepositFactor: Balance = deposit(0, 32);
ddorgan's avatar
ddorgan committed
569
570
571
	pub const MaxSignatories: u16 = 100;
}

572
impl pallet_multisig::Config for Runtime {
ddorgan's avatar
ddorgan committed
573
574
575
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
576
577
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
ddorgan's avatar
ddorgan committed
578
	type MaxSignatories = MaxSignatories;
579
	type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
580
581
582
}

parameter_types! {
583
	pub const ConfigDepositBase: Balance = 500 * CENTS;
ddorgan's avatar
ddorgan committed
584
585
	pub const FriendDepositFactor: Balance = 50 * CENTS;
	pub const MaxFriends: u16 = 9;
586
	pub const RecoveryDeposit: Balance = 500 * CENTS;
ddorgan's avatar
ddorgan committed
587
588
}

589
impl pallet_recovery::Config for Runtime {
ddorgan's avatar
ddorgan committed
590
591
592
593
594
595
596
597
598
599
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
	type ConfigDepositBase = ConfigDepositBase;
	type FriendDepositFactor = FriendDepositFactor;
	type MaxFriends = MaxFriends;
	type RecoveryDeposit = RecoveryDeposit;
}

parameter_types! {
600
	pub const MinVestedTransfer: Balance = 100 * CENTS;
ddorgan's avatar
ddorgan committed
601
602
}

603
impl pallet_vesting::Config for Runtime {
ddorgan's avatar
ddorgan committed
604
605
606
607
	type Event = Event;
	type Currency = Balances;
	type BlockNumberToBalance = ConvertInto;
	type MinVestedTransfer = MinVestedTransfer;
608
	type WeightInfo = weights::pallet_vesting::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
609
610
}

611
impl pallet_sudo::Config for Runtime {
ddorgan's avatar
ddorgan committed
612
613
614
615
	type Event = Event;
	type Call = Call;
}

616
617
618
619
620
621
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;
622
623
624
	pub const AnnouncementDepositBase: Balance = deposit(1, 8);
	pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
	pub const MaxPending: u16 = 32;
625
626
627
}

/// The type used to represent the kinds of proxying allowed.
628
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen)]
629
630
631
632
pub enum ProxyType {
	Any,
	NonTransfer,
	Staking,
633
	SudoBalances,
Chevdor's avatar
Chevdor committed
634
	IdentityJudgement,
Shawn Tabrizi's avatar
Shawn Tabrizi committed
635
	CancelProxy,
636
637
638
639
640
641
}
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,
642
643
644
645
			ProxyType::NonTransfer => matches!(c,
				Call::System(..) |
				Call::Babe(..) |
				Call::Timestamp(..) |
646
647
648
				Call::Indices(pallet_indices::Call::claim(..)) |
				Call::Indices(pallet_indices::Call::free(..)) |
				Call::Indices(pallet_indices::Call::freeze(..)) |
649
650
651
652
653
654
655
656
657
658
659
				// Specifically omitting Indices `transfer`, `force_transfer`
				// Specifically omitting the entire Balances pallet
				Call::Authorship(..) |
				Call::Staking(..) |
				Call::Offences(..) |
				Call::Session(..) |
				Call::Grandpa(..) |
				Call::ImOnline(..) |
				Call::AuthorityDiscovery(..) |
				Call::Utility(..) |
				Call::Identity(..) |
660
661
662
663
664
665
				Call::Recovery(pallet_recovery::Call::as_recovered(..)) |
				Call::Recovery(pallet_recovery::Call::vouch_recovery(..)) |
				Call::Recovery(pallet_recovery::Call::claim_recovery(..)) |
				Call::Recovery(pallet_recovery::Call::close_recovery(..)) |
				Call::Recovery(pallet_recovery::Call::remove_recovery(..)) |
				Call::Recovery(pallet_recovery::Call::cancel_recovered(..)) |
666
				// Specifically omitting Recovery `create_recovery`, `initiate_recovery`
667
668
				Call::Vesting(pallet_vesting::Call::vest(..)) |
				Call::Vesting(pallet_vesting::Call::vest_other(..)) |
669
670
671
672
				// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
				Call::Scheduler(..) |
				// Specifically omitting Sudo pallet
				Call::Proxy(..) |
673
674
675
676
677
678
679
680
681
				Call::Multisig(..) |
				Call::Registrar(paras_registrar::Call::register(..)) |
				Call::Registrar(paras_registrar::Call::deregister(..)) |
				// Specifically omitting Registrar `swap`
				Call::Registrar(paras_registrar::Call::reserve(..)) |
				Call::Crowdloan(..) |
				Call::Slots(..) |
				Call::Auctions(..)
				// Specifically omitting the entire XCM Pallet
682
683
			),
			ProxyType::Staking => matches!(c,
Shawn Tabrizi's avatar
Shawn Tabrizi committed
684
685
686
				Call::Staking(..) |
				Call::Session(..) |
				Call::Utility(..)
687
			),
688
			ProxyType::SudoBalances => match c {
689
				Call::Sudo(pallet_sudo::Call::sudo(ref x)) => matches!(x.as_ref(), &Call::Balances(..)),
Gavin Wood's avatar
Gavin Wood committed
690
				Call::Utility(..) => true,
691
692
				_ => false,
			},
Chevdor's avatar
Chevdor committed
693
			ProxyType::IdentityJudgement => matches!(c,
Shawn Tabrizi's avatar
Shawn Tabrizi committed
694
695
				Call::Identity(pallet_identity::Call::provide_judgement(..)) |
				Call::Utility(..)
Shawn Tabrizi's avatar
Shawn Tabrizi committed
696
697
			),
			ProxyType::CancelProxy => matches!(c,
698
				Call::Proxy(pallet_proxy::Call::reject_announcement(..))
Chevdor's avatar
Chevdor committed
699
			)
700
701
702
703
704
705
706
707
708
		}
	}
	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,
709
710
711
712
		}
	}
}

713
impl pallet_proxy::Config for Runtime {
714
715
716
717
718
719
720
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
	type ProxyType = ProxyType;
	type ProxyDepositBase = ProxyDepositBase;
	type ProxyDepositFactor = ProxyDepositFactor;
	type MaxProxies = MaxProxies;
721
	type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
722
723
724
725
	type MaxPending = MaxPending;
	type CallHasher = BlakeTwo256;
	type AnnouncementDepositBase = AnnouncementDepositBase;
	type AnnouncementDepositFactor = AnnouncementDepositFactor;
726
727
}

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
impl parachains_origin::Config for Runtime {}

impl parachains_configuration::Config for Runtime {}

impl parachains_shared::Config for Runtime {}

impl parachains_session_info::Config for Runtime {}

impl parachains_inclusion::Config for Runtime {
	type Event = Event;
	type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints<Runtime>;
}

impl parachains_paras::Config for Runtime {
	type Origin = Origin;
	type Event = Event;
}

parameter_types! {
	pub const FirstMessageFactorPercent: u64 = 100;
}

impl parachains_ump::Config for Runtime {
751
752
	type Event = Event;
	type UmpSink = crate::parachains_ump::XcmSink<XcmExecutor<XcmConfig>, Runtime>;
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
	type FirstMessageFactorPercent = FirstMessageFactorPercent;
}

impl parachains_dmp::Config for Runtime {}

impl parachains_hrmp::Config for Runtime {
	type Event = Event;
	type Origin = Origin;
	type Currency = Balances;
}

impl parachains_paras_inherent::Config for Runtime {}

impl parachains_scheduler::Config for Runtime {}

impl parachains_initializer::Config for Runtime {
	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
	type ForceOrigin = EnsureRoot<AccountId>;
}

impl paras_sudo_wrapper::Config for Runtime {}

parameter_types! {
	pub const ParaDeposit: Balance = 2000 * CENTS;
	pub const DataDepositPerByte: Balance = deposit(0, 1);
	pub const MaxCodeSize: u32 = 5 * 1024 * 1024; // 10 MB
	pub const MaxHeadSize: u32 = 20 * 1024; // 20 KB
}

impl paras_registrar::Config for Runtime {
	type Event = Event;
	type Origin = Origin;
	type Currency = Balances;
786
	type OnSwap = (Crowdloan, Slots);
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
	type ParaDeposit = ParaDeposit;
	type DataDepositPerByte = DataDepositPerByte;
	type MaxCodeSize = MaxCodeSize;
	type MaxHeadSize = MaxHeadSize;
	type WeightInfo = weights::runtime_common_paras_registrar::WeightInfo<Runtime>;
}

parameter_types! {
	pub const LeasePeriod: BlockNumber = 28 * DAYS;
}

impl slots::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
	type Registrar = Registrar;
	type LeasePeriod = LeasePeriod;
	type WeightInfo = weights::runtime_common_slots::WeightInfo<Runtime>;
}

806
807
808
809
810
811
812
813
814
815
816
817
818
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
parameter_types! {
	pub const CrowdloanId: PalletId = PalletId(*b"py/cfund");
	pub const SubmissionDeposit: Balance = 100 * 100 * CENTS;
	pub const MinContribution: Balance = 100 * CENTS;
	pub const RemoveKeysLimit: u32 = 500;
	// Allow 32 bytes for an additional memo to a crowdloan.
	pub const MaxMemoLength: u8 = 32;
}

impl crowdloan::Config for Runtime {
	type Event = Event;
	type PalletId = CrowdloanId;
	type SubmissionDeposit = SubmissionDeposit;
	type MinContribution = MinContribution;
	type RemoveKeysLimit = RemoveKeysLimit;
	type Registrar = Registrar;
	type Auctioneer = Auctions;
	type MaxMemoLength = MaxMemoLength;
	type WeightInfo = weights::runtime_common_crowdloan::WeightInfo<Runtime>;
}

parameter_types! {
	// The average auction is 7 days long, so this will be 70% for ending period.
	// 5 Days = 72000 Blocks @ 6 sec per block
	pub const EndingPeriod: BlockNumber = 5 * DAYS;
	// ~ 1000 samples per day -> ~ 20 blocks per sample -> 2 minute samples
	pub const SampleLength: BlockNumber = 2 * MINUTES;
}

impl auctions::Config for Runtime {
	type Event = Event;
	type Leaser = Slots;
	type Registrar = Registrar;
	type EndingPeriod = EndingPeriod;
	type SampleLength = SampleLength;
	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
	type InitiateOrigin = EnsureRoot<AccountId>;
	type WeightInfo = weights::runtime_common_auctions::WeightInfo<Runtime>;
}

846
847
848
849
parameter_types! {
	pub const WndLocation: MultiLocation = MultiLocation::Null;
	pub const Ancestry: MultiLocation = MultiLocation::Null;
	pub WestendNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
850
	pub CheckAccount: AccountId = XcmPallet::check_account();
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
}

pub type LocationConverter = (
	ChildParachainConvertsVia<ParaId, AccountId>,
	AccountId32Aliases<WestendNetwork, AccountId>,
);

pub type LocalAssetTransactor =
	XcmCurrencyAdapter<
		// Use this currency:
		Balances,
		// Use this currency when it is a fungible asset matching the given location or name:
		IsConcrete<WndLocation>,
		// We can convert the MultiLocations with our converter above:
		LocationConverter,
		// Our chain's account ID type (we can't get away without mentioning it explicitly):
		AccountId,
868
869
		// It's a native asset so we keep track of the teleports to maintain total issuance.
		CheckAccount,
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
	>;

type LocalOriginConverter = (
	SovereignSignedViaLocation<LocationConverter, Origin>,
	ChildParachainAsNative<parachains_origin::Origin, Origin>,
	SignedAccountId32AsNative<WestendNetwork, Origin>,
	ChildSystemParachainAsSuperuser<ParaId, Origin>,
);

parameter_types! {
	pub const BaseXcmWeight: Weight = 10_000_000;
}

/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our
/// individual routers.
pub type XcmRouter = (
	// Only one router so far - use DMP to communicate with child parachains.
	xcm_sender::ChildParachainRouter<Runtime>,
);

890
891
892
893
894
895
896
897
parameter_types! {
	pub const WestendForWestmint: (MultiAsset, MultiLocation) =
		(AllConcreteFungible { id: Null }, X1(Parachain(1000)));
}
pub type TrustedTeleporters = (
	xcm_builder::Case<WestendForWestmint>,
);

898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
/// The barriers one of which must be passed for an XCM message to be executed.
pub type Barrier = (
	// Weight that is paid for may be consumed.
	TakeWeightCredit,
	// If the message is one that immediately attemps to pay for execution, then allow it.
	AllowTopLevelPaidExecutionFrom<All<MultiLocation>>,
	// Messages coming from system parachains need not pay for execution.
	AllowUnpaidExecutionFrom<IsChildSystemParachain<ParaId>>,
);

pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
	type Call = Call;
	type XcmSender = XcmRouter;
	type AssetTransactor = LocalAssetTransactor;
	type OriginConverter = LocalOriginConverter;
	type IsReserve = ();
915
	type IsTeleporter = TrustedTeleporters;
916
	type LocationInverter = LocationInverter<Ancestry>;
917
	type Barrier = Barrier;
918
919
920
921
922
	type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
	type Trader = UsingComponents<WeightToFee, WndLocation, AccountId, Balances, ToAuthor<Runtime>>;
	type ResponseHandler = ();
}

923
924
925
926
927
928
929
930
931
932
933
934
/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior location
/// of this chain.
pub type LocalOriginToLocation = (
	// And a usual Signed origin to be used in XCM as a corresponding AccountId32
	SignedToAccountId32<Origin, AccountId, WestendNetwork>,
);

pub struct OnlyWithdrawTeleportForAccounts;
impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdrawTeleportForAccounts {
	fn contains((ref origin, ref msg): &(MultiLocation, Xcm<Call>)) -> bool {
		use xcm::v0::{
			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
935
			MultiAsset::{All, ConcreteFungible}, Junction::AccountId32,
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
		};
		match origin {
			// Root is allowed to execute anything.
			Null => true,
			X1(AccountId32 { .. }) => {
				// An account ID trying to send a message. We ensure that it's sensible.
				// This checks that it's of the form:
				// WithdrawAsset {
				//   assets: [ ConcreteFungible { id: Null } ],
				//   effects: [ BuyExecution, InitiateTeleport {
				//     assets: All,
				//     dest: Parachain,
				//     effects: [ BuyExecution, DepositAssets {
				//       assets: All,
				//       dest: AccountId32,
				//     } ]
				//   } ]
				// }
				matches!(msg, WithdrawAsset { ref assets, ref effects }
					if assets.len() == 1
					&& matches!(assets[0], ConcreteFungible { id: Null, .. })
					&& effects.len() == 2
					&& matches!(effects[0], BuyExecution { .. })
					&& matches!(effects[1], InitiateTeleport { ref assets, dest: X1(Parachain(..)), ref effects }
						if assets.len() == 1
						&& matches!(assets[0], All)
						&& effects.len() == 2
						&& matches!(effects[0], BuyExecution { .. })
						&& matches!(effects[1], DepositAsset { ref assets, dest: X1(AccountId32{..}) }
							if assets.len() == 1
							&& matches!(assets[0], All)
						)
					)
				)
			}
			// Nobody else is allowed to execute anything.
			_ => false,
		}
	}
}

impl pallet_xcm::Config for Runtime {
	type Event = Event;
	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
	type XcmRouter = XcmRouter;
	// Anyone can execute XCM messages locally...
	type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
	// ...but they must match our filter, which requires them to be a simple withdraw + teleport.
	type XcmExecuteFilter = OnlyWithdrawTeleportForAccounts;
	type XcmExecutor = XcmExecutor<XcmConfig>;
986
	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
987
	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
988
	type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
989
990
}

ddorgan's avatar
ddorgan committed
991
992
993
construct_runtime! {
	pub enum Runtime where
		Block = Block,
994
		NodeBlock = primitives::v1::Block,
ddorgan's avatar
ddorgan committed
995
996
997
		UncheckedExtrinsic = UncheckedExtrinsic
	{
		// Basic stuff; balances is uncallable initially.
998
999
		System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 0,
		RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 25,
ddorgan's avatar
ddorgan committed
1000

For faster browsing, not all history is shown. View entire blame