lib.rs 56.2 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;
24
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
25
use primitives::v1::{
26
	AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
27
	CoreState, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage,
28
29
	Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes,
	SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
ddorgan's avatar
ddorgan committed
30
};
31
use runtime_common::{
32
33
34
35
36
37
38
39
40
41
42
43
44
	auctions, crowdloan, impls::ToAuthor, paras_registrar, paras_sudo_wrapper, slots, xcm_sender,
	BlockHashCount, BlockLength, BlockWeights, CurrencyToVote, OffchainSolutionLengthLimit,
	OffchainSolutionWeightLimit, RocksDbWeight, SlowAdjustingFeeUpdate,
};
use sp_std::{collections::btree_map::BTreeMap, prelude::*};

use runtime_parachains::{
	configuration as parachains_configuration, dmp as parachains_dmp, hrmp as parachains_hrmp,
	inclusion as parachains_inclusion, initializer as parachains_initializer,
	origin as parachains_origin, paras as parachains_paras,
	paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points,
	runtime_api_impl::v1 as parachains_runtime_api_impl, scheduler as parachains_scheduler,
	session_info as parachains_session_info, shared as parachains_shared, ump as parachains_ump,
ddorgan's avatar
ddorgan committed
45
};
46

Gavin Wood's avatar
Gavin Wood committed
47
use xcm::latest::prelude::*;
48
use xcm_builder::{
49
50
51
	AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
	AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, ChildParachainAsNative,
	ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
52
53
54
	CurrencyAdapter as XcmCurrencyAdapter, IsChildSystemParachain, IsConcrete, LocationInverter,
	SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
	UsingComponents, WeightInfoBounds,
55
};
56
use xcm_executor::XcmExecutor;
57

58
59
60
61
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use beefy_primitives::crypto::AuthorityId as BeefyId;
use frame_support::{
	construct_runtime, parameter_types,
62
	traits::{Contains, Everything, InstanceFilter, KeyOwnerProofSystem, Nothing},
63
64
65
66
67
68
69
70
71
72
	weights::Weight,
	PalletId, RuntimeDebug,
};
use frame_system::EnsureRoot;
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use pallet_mmr_primitives as mmr;
use pallet_session::historical as session_historical;
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
use sp_core::OpaqueMetadata;
ddorgan's avatar
ddorgan committed
73
use sp_runtime::{
74
75
76
	create_runtime_str,
	curve::PiecewiseLinear,
	generic, impl_opaque_keys,
ddorgan's avatar
ddorgan committed
77
	traits::{
78
79
		AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT,
		OpaqueKeys, SaturatedConversion, Verify,
ddorgan's avatar
ddorgan committed
80
	},
81
82
	transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
	ApplyExtrinsicResult, KeyTypeId, Perbill,
ddorgan's avatar
ddorgan committed
83
};
84
use sp_staking::SessionIndex;
ddorgan's avatar
ddorgan committed
85
#[cfg(any(feature = "std", test))]
86
use sp_version::NativeVersion;
87
use sp_version::RuntimeVersion;
ddorgan's avatar
ddorgan committed
88

89
90
pub use pallet_balances::Call as BalancesCall;
pub use pallet_election_provider_multi_phase::Call as EPMCall;
ddorgan's avatar
ddorgan committed
91
#[cfg(feature = "std")]
92
pub use pallet_staking::StakerStatus;
93
pub use pallet_timestamp::Call as TimestampCall;
ddorgan's avatar
ddorgan committed
94
95
96
97
98
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;

/// Constant values used within the runtime.
pub mod constants;
99
use constants::{currency::*, fee::*, time::*};
ddorgan's avatar
ddorgan committed
100

101
102
103
// Weights used in the runtime
mod weights;

104
// Voter bag threshold definitions.
105
mod bag_thresholds;
106

107
108
109
#[cfg(test)]
mod tests;

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

114
/// Runtime version (Westend).
ddorgan's avatar
ddorgan committed
115
116
117
118
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("westend"),
	impl_name: create_runtime_str!("parity-westend"),
	authoring_version: 2,
Bastian Köcher's avatar
Bastian Köcher committed
119
	spec_version: 9130,
120
	impl_version: 0,
121
	#[cfg(not(feature = "disable-runtime-api"))]
ddorgan's avatar
ddorgan committed
122
	apis: RUNTIME_API_VERSIONS,
123
	#[cfg(feature = "disable-runtime-api")]
124
	apis: version::create_apis_vec![[]],
125
	transaction_version: 7,
ddorgan's avatar
ddorgan committed
126
127
};

128
129
130
131
/// The BABE epoch configuration at genesis.
pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration =
	babe_primitives::BabeEpochConfiguration {
		c: PRIMARY_PROBABILITY,
132
		allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots,
133
134
	};

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

141
/// Allow everything.
142
pub struct BaseFilter;
143
144
impl Contains<Call> for BaseFilter {
	fn contains(_: &Call) -> bool {
145
		true
ddorgan's avatar
ddorgan committed
146
147
148
149
150
	}
}

parameter_types! {
	pub const Version: RuntimeVersion = VERSION;
151
	pub const SS58Prefix: u8 = 42;
ddorgan's avatar
ddorgan committed
152
153
}

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

180
parameter_types! {
181
182
	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
		BlockWeights::get().max_block;
183
184
185
	pub const MaxScheduledPerBlock: u32 = 50;
}

186
impl pallet_scheduler::Config for Runtime {
ddorgan's avatar
ddorgan committed
187
188
	type Event = Event;
	type Origin = Origin;
189
	type PalletsOrigin = OriginCaller;
ddorgan's avatar
ddorgan committed
190
	type Call = Call;
191
	type MaximumWeight = MaximumSchedulerWeight;
192
	type ScheduleOrigin = EnsureRoot<AccountId>;
193
	type MaxScheduledPerBlock = MaxScheduledPerBlock;
194
	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
195
196
197
}

parameter_types! {
198
	pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
ddorgan's avatar
ddorgan committed
199
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
200
201
	pub const ReportLongevity: u64 =
		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
ddorgan's avatar
ddorgan committed
202
203
}

204
impl pallet_babe::Config for Runtime {
ddorgan's avatar
ddorgan committed
205
206
207
208
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;

	// session module is the trigger
209
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
210

211
212
	type DisabledValidators = Session;

213
214
215
216
	type KeyOwnerProofSystem = Historical;

	type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
217
		pallet_babe::AuthorityId,
218
219
220
221
	)>>::Proof;

	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
222
		pallet_babe::AuthorityId,
223
224
225
	)>>::IdentificationTuple;

	type HandleEquivocation =
226
		pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
227
228

	type WeightInfo = ();
229
230

	type MaxAuthorities = MaxAuthorities;
ddorgan's avatar
ddorgan committed
231
232
233
}

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

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

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

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

parameter_types! {
	pub const TransactionByteFee: Balance = 10 * MILLICENTS;
265
266
267
	/// This value increases the priority of `Operational` transactions by adding
	/// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
	pub const OperationalFeeMultiplier: u8 = 5;
ddorgan's avatar
ddorgan committed
268
269
}

270
impl pallet_transaction_payment::Config for Runtime {
Albrecht's avatar
Albrecht committed
271
	type OnChargeTransaction = CurrencyAdapter<Balances, ToAuthor<Runtime>>;
ddorgan's avatar
ddorgan committed
272
	type TransactionByteFee = TransactionByteFee;
273
	type OperationalFeeMultiplier = OperationalFeeMultiplier;
ddorgan's avatar
ddorgan committed
274
	type WeightToFee = WeightToFee;
275
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
ddorgan's avatar
ddorgan committed
276
277
278
279
280
}

parameter_types! {
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
}
281
impl pallet_timestamp::Config for Runtime {
ddorgan's avatar
ddorgan committed
282
283
284
	type Moment = u64;
	type OnTimestampSet = Babe;
	type MinimumPeriod = MinimumPeriod;
285
	type WeightInfo = weights::pallet_timestamp::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
286
287
288
289
290
291
}

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

292
impl pallet_authorship::Config for Runtime {
293
	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
ddorgan's avatar
ddorgan committed
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
	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,
309
		pub para_validator: Initializer,
310
		pub para_assignment: ParaSessionInfo,
ddorgan's avatar
ddorgan committed
311
312
313
314
		pub authority_discovery: AuthorityDiscovery,
	}
}

315
impl pallet_session::Config for Runtime {
ddorgan's avatar
ddorgan committed
316
317
	type Event = Event;
	type ValidatorId = AccountId;
318
	type ValidatorIdOf = pallet_staking::StashOf<Self>;
ddorgan's avatar
ddorgan committed
319
320
	type ShouldEndSession = Babe;
	type NextSessionRotation = Babe;
321
	type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
ddorgan's avatar
ddorgan committed
322
323
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
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
parameter_types! {
333
334
	// phase durations. 1/4 of the last session for each.
	pub const SignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
335
	pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
336

337
338
	// signed config
	pub const SignedMaxSubmissions: u32 = 128;
339
340
	pub const SignedDepositBase: Balance = deposit(2, 0);
	pub const SignedDepositByte: Balance = deposit(0, 10) / 1024;
341
342
	// Each good submission will get 1 WND as reward
	pub SignedRewardBase: Balance = 1 * UNITS;
343
	pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(5u32, 10_000);
344

345
346
	// 1 hour session, 15 minutes unsigned phase, 4 offchain executions.
	pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 4;
347
348
349
350
351

	/// Whilst `UseNominatorsAndUpdateBagsList` or `UseNominatorsMap` is in use, this can still be a
	/// very large value. Once the `BagsList` is in full motion, staking might open its door to many
	/// more nominators, and this value should instead be what is a "safe" number (e.g. 22500).
	pub const VoterSnapshotPerBlock: u32 = 22_500;
352
353
}

354
355
sp_npos_elections::generate_solution_type!(
	#[compact]
356
357
358
359
360
	pub struct NposCompactSolution16::<
		VoterIndex = u32,
		TargetIndex = u16,
		Accuracy = sp_runtime::PerU16,
	>(16)
361
362
);

363
364
365
impl pallet_election_provider_multi_phase::Config for Runtime {
	type Event = Event;
	type Currency = Balances;
366
	type EstimateCallFee = TransactionPayment;
367
368
	type SignedPhase = SignedPhase;
	type UnsignedPhase = UnsignedPhase;
369
370
371
372
373
374
375
376
	type SignedMaxSubmissions = SignedMaxSubmissions;
	type SignedRewardBase = SignedRewardBase;
	type SignedDepositBase = SignedDepositBase;
	type SignedDepositByte = SignedDepositByte;
	type SignedDepositWeight = ();
	type SignedMaxWeight = Self::MinerMaxWeight;
	type SlashHandler = (); // burn slashes
	type RewardHandler = (); // nothing to do upon rewards
377
	type SolutionImprovementThreshold = SolutionImprovementThreshold;
378
	type MinerMaxWeight = OffchainSolutionWeightLimit; // For now use the one from staking.
379
	type MinerMaxLength = OffchainSolutionLengthLimit;
380
	type OffchainRepeat = OffchainRepeat;
381
	type MinerTxPriority = NposSolutionPriority;
382
	type DataProvider = Staking;
383
	type Solution = NposCompactSolution16;
Kian Paimani's avatar
Kian Paimani committed
384
	type Fallback = pallet_election_provider_multi_phase::NoFallback<Self>;
385
386
	type Solver = frame_election_provider_support::SequentialPhragmen<
		AccountId,
Kian Paimani's avatar
Kian Paimani committed
387
		pallet_election_provider_multi_phase::SolutionAccuracyOf<Self>,
388
389
		runtime_common::elections::OffchainRandomBalancing,
	>;
390
	type BenchmarkingConfig = runtime_common::elections::BenchmarkConfig;
391
	type ForceOrigin = EnsureRoot<AccountId>;
Kian Paimani's avatar
Kian Paimani committed
392
	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Self>;
393
394
395
396
	type VoterSnapshotPerBlock = VoterSnapshotPerBlock;
}

parameter_types! {
397
	pub const BagThresholds: &'static [u64] = &bag_thresholds::THRESHOLDS;
398
399
400
401
402
403
404
}

impl pallet_bags_list::Config for Runtime {
	type Event = Event;
	type VoteWeightProvider = Staking;
	type WeightInfo = weights::pallet_bags_list::WeightInfo<Runtime>;
	type BagThresholds = BagThresholds;
405
406
}

ddorgan's avatar
ddorgan committed
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
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).
422
	pub const BondingDuration: pallet_staking::EraIndex = 28;
423
	// 27 eras in which slashes can be cancelled (slightly less than 7 days).
424
	pub const SlashDeferDuration: pallet_staking::EraIndex = 27;
ddorgan's avatar
ddorgan committed
425
426
	pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
	pub const MaxNominatorRewardedPerValidator: u32 = 64;
427
	pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17);
ddorgan's avatar
ddorgan committed
428
429
}

Kian Paimani's avatar
Kian Paimani committed
430
431
432
433
434
impl frame_election_provider_support::onchain::Config for Runtime {
	type Accuracy = runtime_common::elections::OnOnChainAccuracy;
	type DataProvider = Staking;
}

435
impl pallet_staking::Config for Runtime {
436
	const MAX_NOMINATIONS: u32 =
437
		<NposCompactSolution16 as sp_npos_elections::NposSolution>::LIMIT as u32;
ddorgan's avatar
ddorgan committed
438
439
	type Currency = Balances;
	type UnixTime = Timestamp;
440
	type CurrencyToVote = CurrencyToVote;
ddorgan's avatar
ddorgan committed
441
442
443
444
445
446
447
448
	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.
449
	type SlashCancelOrigin = EnsureRoot<AccountId>;
ddorgan's avatar
ddorgan committed
450
	type SessionInterface = Self;
Kian Paimani's avatar
Kian Paimani committed
451
	type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
ddorgan's avatar
ddorgan committed
452
	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
453
	type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
ddorgan's avatar
ddorgan committed
454
	type NextNewSession = Session;
455
	type ElectionProvider = ElectionProviderMultiPhase;
Kian Paimani's avatar
Kian Paimani committed
456
	type GenesisElectionProvider = runtime_common::elections::GenesisElectionOf<Self>;
457
	// Use the nominators map to iter voters, but also keep bags-list up-to-date.
458
	type SortedListProvider = runtime_common::elections::UseNominatorsAndUpdateBagsList<Runtime>;
459
	type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
460
461
462
463
464
465
}

parameter_types! {
	pub const LaunchPeriod: BlockNumber = 7 * DAYS;
	pub const VotingPeriod: BlockNumber = 7 * DAYS;
	pub const FastTrackVotingPeriod: BlockNumber = 3 * HOURS;
466
	pub const MinimumDeposit: Balance = 100 * CENTS;
ddorgan's avatar
ddorgan committed
467
468
469
470
471
	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;
472
	pub const MaxAuthorities: u32 = 100_000;
ddorgan's avatar
ddorgan committed
473
474
}

475
impl pallet_offences::Config for Runtime {
ddorgan's avatar
ddorgan committed
476
	type Event = Event;
477
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
ddorgan's avatar
ddorgan committed
478
479
480
	type OnOffenceHandler = Staking;
}

481
482
483
impl pallet_authority_discovery::Config for Runtime {
	type MaxAuthorities = MaxAuthorities;
}
ddorgan's avatar
ddorgan committed
484
485

parameter_types! {
486
	pub const NposSolutionPriority: TransactionPriority = TransactionPriority::max_value() / 2;
ddorgan's avatar
ddorgan committed
487
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
488
489
490
	pub const MaxKeys: u32 = 10_000;
	pub const MaxPeerInHeartbeats: u32 = 10_000;
	pub const MaxPeerDataEncodingSize: u32 = 1_000;
ddorgan's avatar
ddorgan committed
491
492
}

493
impl pallet_im_online::Config for Runtime {
ddorgan's avatar
ddorgan committed
494
495
	type AuthorityId = ImOnlineId;
	type Event = Event;
496
	type ValidatorSet = Historical;
497
	type NextSessionRotation = Babe;
ddorgan's avatar
ddorgan committed
498
	type ReportUnresponsiveness = Offences;
499
	type UnsignedPriority = ImOnlineUnsignedPriority;
500
	type WeightInfo = weights::pallet_im_online::WeightInfo<Runtime>;
501
502
503
	type MaxKeys = MaxKeys;
	type MaxPeerInHeartbeats = MaxPeerInHeartbeats;
	type MaxPeerDataEncodingSize = MaxPeerDataEncodingSize;
ddorgan's avatar
ddorgan committed
504
505
}

506
impl pallet_grandpa::Config for Runtime {
ddorgan's avatar
ddorgan committed
507
	type Event = Event;
508
509
510
511
512
513
514
515
516
517
518
519
	type Call = Call;

	type KeyOwnerProofSystem = Historical;

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

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

520
521
522
523
524
	type HandleEquivocation = pallet_grandpa::EquivocationHandler<
		Self::KeyOwnerIdentification,
		Offences,
		ReportLongevity,
	>;
525
526

	type WeightInfo = ();
527
	type MaxAuthorities = MaxAuthorities;
ddorgan's avatar
ddorgan committed
528
529
}

530
531
/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
532
533
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
where
534
535
	Call: From<LocalCall>,
{
536
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
537
538
539
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
540
		nonce: <Runtime as frame_system::Config>::Index,
541
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
542
		use sp_runtime::traits::StaticLookup;
543
		// take the biggest period possible.
544
545
		let period =
			BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
546
547
548

		let current_block = System::block_number()
			.saturated_into::<u64>()
549
550
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
551
552
553
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
554
555
556
			frame_system::CheckSpecVersion::<Runtime>::new(),
			frame_system::CheckTxVersion::<Runtime>::new(),
			frame_system::CheckGenesis::<Runtime>::new(),
557
558
559
560
			frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal(
				period,
				current_block,
			)),
561
562
563
			frame_system::CheckNonce::<Runtime>::from(nonce),
			frame_system::CheckWeight::<Runtime>::new(),
			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
564
		);
565
566
567
568
569
570
		let raw_payload = SignedPayload::new(call, extra)
			.map_err(|e| {
				log::warn!("Unable to create signed payload: {:?}", e);
			})
			.ok()?;
		let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
571
		let (call, extra, _) = raw_payload.deconstruct();
572
573
		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
		Some((call, (address, signature, extra)))
574
	}
ddorgan's avatar
ddorgan committed
575
576
}

577
impl frame_system::offchain::SigningTypes for Runtime {
578
579
580
581
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

582
583
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
where
584
585
586
587
588
589
	Call: From<C>,
{
	type OverarchingCall = Call;
	type Extrinsic = UncheckedExtrinsic;
}

ddorgan's avatar
ddorgan committed
590
591
parameter_types! {
	// Minimum 100 bytes/KSM deposited (1 CENT/byte)
592
	pub const BasicDeposit: Balance = 1000 * CENTS;       // 258 bytes on-chain
ddorgan's avatar
ddorgan committed
593
	pub const FieldDeposit: Balance = 250 * CENTS;        // 66 bytes on-chain
594
	pub const SubAccountDeposit: Balance = 200 * CENTS;   // 53 bytes on-chain
ddorgan's avatar
ddorgan committed
595
596
	pub const MaxSubAccounts: u32 = 100;
	pub const MaxAdditionalFields: u32 = 100;
597
	pub const MaxRegistrars: u32 = 20;
ddorgan's avatar
ddorgan committed
598
599
}

600
impl pallet_identity::Config for Runtime {
ddorgan's avatar
ddorgan committed
601
602
603
604
605
606
607
608
	type Event = Event;
	type Currency = Balances;
	type Slashed = ();
	type BasicDeposit = BasicDeposit;
	type FieldDeposit = FieldDeposit;
	type SubAccountDeposit = SubAccountDeposit;
	type MaxSubAccounts = MaxSubAccounts;
	type MaxAdditionalFields = MaxAdditionalFields;
609
	type MaxRegistrars = MaxRegistrars;
610
611
	type RegistrarOrigin = frame_system::EnsureRoot<AccountId>;
	type ForceOrigin = frame_system::EnsureRoot<AccountId>;
612
	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
613
614
}

615
impl pallet_utility::Config for Runtime {
616
617
	type Event = Event;
	type Call = Call;
618
	type WeightInfo = weights::pallet_utility::WeightInfo<Runtime>;
619
620
}

ddorgan's avatar
ddorgan committed
621
parameter_types! {
622
623
	// 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
624
	// Additional storage item size of 32 bytes.
625
	pub const DepositFactor: Balance = deposit(0, 32);
ddorgan's avatar
ddorgan committed
626
627
628
	pub const MaxSignatories: u16 = 100;
}

629
impl pallet_multisig::Config for Runtime {
ddorgan's avatar
ddorgan committed
630
631
632
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
633
634
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
ddorgan's avatar
ddorgan committed
635
	type MaxSignatories = MaxSignatories;
636
	type WeightInfo = weights::pallet_multisig::WeightInfo<Runtime>;
ddorgan's avatar
ddorgan committed
637
638
639
}

parameter_types! {
640
	pub const ConfigDepositBase: Balance = 500 * CENTS;
ddorgan's avatar
ddorgan committed
641
642
	pub const FriendDepositFactor: Balance = 50 * CENTS;
	pub const MaxFriends: u16 = 9;
643
	pub const RecoveryDeposit: Balance = 500 * CENTS;
ddorgan's avatar
ddorgan committed
644
645
}

646
impl pallet_recovery::Config for Runtime {
ddorgan's avatar
ddorgan committed
647
648
649
650
651
652
653
654
655
656
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
	type ConfigDepositBase = ConfigDepositBase;
	type FriendDepositFactor = FriendDepositFactor;
	type MaxFriends = MaxFriends;
	type RecoveryDeposit = RecoveryDeposit;
}

parameter_types! {
657
	pub const MinVestedTransfer: Balance = 100 * CENTS;
ddorgan's avatar
ddorgan committed
658
659
}

660
impl pallet_vesting::Config for Runtime {
ddorgan's avatar
ddorgan committed
661
662
663
664
	type Event = Event;
	type Currency = Balances;
	type BlockNumberToBalance = ConvertInto;
	type MinVestedTransfer = MinVestedTransfer;
665
	type WeightInfo = weights::pallet_vesting::WeightInfo<Runtime>;
666
	const MAX_VESTING_SCHEDULES: u32 = 28;
ddorgan's avatar
ddorgan committed
667
668
}

669
impl pallet_sudo::Config for Runtime {
ddorgan's avatar
ddorgan committed
670
671
672
673
	type Event = Event;
	type Call = Call;
}

674
675
676
677
678
679
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;
680
681
682
	pub const AnnouncementDepositBase: Balance = deposit(1, 8);
	pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
	pub const MaxPending: u16 = 32;
683
684
685
}

/// The type used to represent the kinds of proxying allowed.
686
#[derive(
687
688
689
690
691
692
693
694
695
696
697
	Copy,
	Clone,
	Eq,
	PartialEq,
	Ord,
	PartialOrd,
	Encode,
	Decode,
	RuntimeDebug,
	MaxEncodedLen,
	scale_info::TypeInfo,
698
)]
699
700
701
702
pub enum ProxyType {
	Any,
	NonTransfer,
	Staking,
703
	SudoBalances,
Chevdor's avatar
Chevdor committed
704
	IdentityJudgement,
Shawn Tabrizi's avatar
Shawn Tabrizi committed
705
	CancelProxy,
706
	Auction,
707
}
708
709
710
711
712
impl Default for ProxyType {
	fn default() -> Self {
		Self::Any
	}
}
713
714
715
716
impl InstanceFilter<Call> for ProxyType {
	fn filter(&self, c: &Call) -> bool {
		match self {
			ProxyType::Any => true,
717
718
			ProxyType::NonTransfer => matches!(
				c,
719
720
721
				Call::System(..) |
				Call::Babe(..) |
				Call::Timestamp(..) |
722
723
724
				Call::Indices(pallet_indices::Call::claim{..}) |
				Call::Indices(pallet_indices::Call::free{..}) |
				Call::Indices(pallet_indices::Call::freeze{..}) |
725
726
727
728
729
730
731
732
733
				// Specifically omitting Indices `transfer`, `force_transfer`
				// Specifically omitting the entire Balances pallet
				Call::Authorship(..) |
				Call::Staking(..) |
				Call::Session(..) |
				Call::Grandpa(..) |
				Call::ImOnline(..) |
				Call::Utility(..) |
				Call::Identity(..) |
734
735
736
737
738
739
				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{..}) |
740
				// Specifically omitting Recovery `create_recovery`, `initiate_recovery`
741
742
				Call::Vesting(pallet_vesting::Call::vest{..}) |
				Call::Vesting(pallet_vesting::Call::vest_other{..}) |
743
744
745
746
				// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
				Call::Scheduler(..) |
				// Specifically omitting Sudo pallet
				Call::Proxy(..) |
747
				Call::Multisig(..) |
748
749
				Call::Registrar(paras_registrar::Call::register{..}) |
				Call::Registrar(paras_registrar::Call::deregister{..}) |
750
				// Specifically omitting Registrar `swap`
751
				Call::Registrar(paras_registrar::Call::reserve{..}) |
752
753
				Call::Crowdloan(..) |
				Call::Slots(..) |
754
755
				Call::Auctions(..) | // Specifically omitting the entire XCM Pallet
				Call::BagsList(..)
756
			),
757
758
759
			ProxyType::Staking => {
				matches!(c, Call::Staking(..) | Call::Session(..) | Call::Utility(..))
			},
760
			ProxyType::SudoBalances => match c {
761
				Call::Sudo(pallet_sudo::Call::sudo { call: ref x }) => {
762
763
					matches!(x.as_ref(), &Call::Balances(..))
				},
Gavin Wood's avatar
Gavin Wood committed
764
				Call::Utility(..) => true,
765
766
				_ => false,
			},
767
768
			ProxyType::IdentityJudgement => matches!(
				c,
769
				Call::Identity(pallet_identity::Call::provide_judgement { .. }) | Call::Utility(..)
Shawn Tabrizi's avatar
Shawn Tabrizi committed
770
			),
771
			ProxyType::CancelProxy => {
772
				matches!(c, Call::Proxy(pallet_proxy::Call::reject_announcement { .. }))
773
			},
774
775
776
777
			ProxyType::Auction => matches!(
				c,
				Call::Auctions(..) | Call::Crowdloan(..) | Call::Registrar(..) | Call::Slots(..)
			),
778
779
780
781
782
783
784
785
786
		}
	}
	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,
787
788
789
790
		}
	}
}

791
impl pallet_proxy::Config for Runtime {
792
793
794
795
796
797
798
	type Event = Event;
	type Call = Call;
	type Currency = Balances;
	type ProxyType = ProxyType;
	type ProxyDepositBase = ProxyDepositBase;
	type ProxyDepositFactor = ProxyDepositFactor;
	type MaxProxies = MaxProxies;
799
	type WeightInfo = weights::pallet_proxy::WeightInfo<Runtime>;
800
801
802
803
	type MaxPending = MaxPending;
	type CallHasher = BlakeTwo256;
	type AnnouncementDepositBase = AnnouncementDepositBase;
	type AnnouncementDepositFactor = AnnouncementDepositFactor;
804
805
}

806
807
impl parachains_origin::Config for Runtime {}

808
impl parachains_configuration::Config for Runtime {
809
	type WeightInfo = weights::runtime_parachains_configuration::WeightInfo<Runtime>;
810
}
811
812
813
814
815
816
817

impl parachains_shared::Config for Runtime {}

impl parachains_session_info::Config for Runtime {}

impl parachains_inclusion::Config for Runtime {
	type Event = Event;
asynchronous rob's avatar
asynchronous rob committed
818
	type DisputesHandler = ();
819
820
821
822
823
824
	type RewardValidators = parachains_reward_points::RewardValidatorsWithEraPoints<Runtime>;
}

impl parachains_paras::Config for Runtime {
	type Origin = Origin;
	type Event = Event;
825
	type WeightInfo = weights::runtime_parachains_paras::WeightInfo<Runtime>;
826
827
828
829
830
831
832
}

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

impl parachains_ump::Config for Runtime {
833
834
	type Event = Event;
	type UmpSink = crate::parachains_ump::XcmSink<XcmExecutor<XcmConfig>, Runtime>;
835
	type FirstMessageFactorPercent = FirstMessageFactorPercent;
836
	type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
}

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>;
854
	type WeightInfo = weights::runtime_parachains_initializer::WeightInfo<Runtime>;
855
856
857
858
859
860
861
862
863
864
865
866
867
}

impl paras_sudo_wrapper::Config for Runtime {}

parameter_types! {
	pub const ParaDeposit: Balance = 2000 * CENTS;
	pub const DataDepositPerByte: Balance = deposit(0, 1);
}

impl paras_registrar::Config for Runtime {
	type Event = Event;
	type Origin = Origin;
	type Currency = Balances;
868
	type OnSwap = (Crowdloan, Slots);
869
870
871
872
873
874
875
876
877
878
879
880
881
882
	type ParaDeposit = ParaDeposit;
	type DataDepositPerByte = DataDepositPerByte;
	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;
883
	type LeaseOffset = ();
884
885
886
	type WeightInfo = weights::runtime_common_slots::WeightInfo<Runtime>;
}

887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
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>;
}

927
parameter_types! {
928
929
	pub const WndLocation: MultiLocation = Here.into();
	pub const Ancestry: MultiLocation = Here.into();
930
	pub WestendNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
931
	pub CheckAccount: AccountId = XcmPallet::check_account();
932
933
}

934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
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,
	// It's a native asset so we keep track of the teleports to maintain total issuance.
	CheckAccount,
>;
949
950
951
952
953
954
955
956
957
958
959
960

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

/// 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.
961
	xcm_sender::ChildParachainRouter<Runtime, XcmPallet>,
962
963
);

964
parameter_types! {
965
	pub const Westmint: MultiLocation = Parachain(1000).into();
Gavin Wood's avatar
Gavin Wood committed
966
	pub const WestendForWestmint: (MultiAssetFilter, MultiLocation) =
967
		(Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), Westmint::get());
968
	pub const MaxInstructions: u32 = 100;
969
}
970
pub type TrustedTeleporters = (xcm_builder::Case<WestendForWestmint>,);
971

972
973
974
975
976
/// 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.
977
	AllowTopLevelPaidExecutionFrom<Everything>,
978
979
	// Messages coming from system parachains need not pay for execution.
	AllowUnpaidExecutionFrom<IsChildSystemParachain<ParaId>>,
980
981
982
983
	// Expected responses are OK.
	AllowKnownQueryResponses<XcmPallet>,
	// Subscriptions for version tracking are OK.
	AllowSubscriptionsFrom<Everything>,
984
985
986
987
988
989
990
991
992
);

pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
	type Call = Call;
	type XcmSender = XcmRouter;
	type AssetTransactor = LocalAssetTransactor;
	type OriginConverter = LocalOriginConverter;
	type IsReserve = ();
993
	type IsTeleporter = TrustedTeleporters;
994
	type LocationInverter = LocationInverter<Ancestry>;
995
	type Barrier = Barrier;
996
	type Weigher = WeightInfoBounds<weights::xcm::WestendXcmWeight<Call>, Call, MaxInstructions>;
997
	type Trader = UsingComponents<WeightToFee, WndLocation, AccountId, Balances, ToAuthor<Runtime>>;
998
999
1000
	type ResponseHandler = XcmPallet;
	type AssetTrap = XcmPallet;
	type AssetClaims = XcmPallet;
For faster browsing, not all history is shown. View entire blame