lib.rs 28.2 KB
Newer Older
Fedor Sakharov's avatar
Fedor Sakharov committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Copyright 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/>.

17
//! The Rococo runtime for v1 parachains.
Fedor Sakharov's avatar
Fedor Sakharov committed
18
19
20

#![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"]
Fedor Sakharov's avatar
Fedor Sakharov committed
22

Albrecht's avatar
Albrecht committed
23
use pallet_transaction_payment::CurrencyAdapter;
Fedor Sakharov's avatar
Fedor Sakharov 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;
Fedor Sakharov's avatar
Fedor Sakharov committed
27
28
use primitives::v1::{
	AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
29
	GroupRotationInfo, CoreState, Id, ValidationCode, CandidateEvent,
Fedor Sakharov's avatar
Fedor Sakharov committed
30
	ValidatorId, ValidatorIndex, CommittedCandidateReceipt, OccupiedCoreAssumption,
31
32
	PersistedValidationData, InboundDownwardMessage, InboundHrmpMessage,
	SessionInfo as SessionInfoData,
Fedor Sakharov's avatar
Fedor Sakharov committed
33
34
};
use runtime_common::{
35
	SlowAdjustingFeeUpdate, impls::ToAuthor, BlockHashCount, BlockWeights, BlockLength, RocksDbWeight,
Fedor Sakharov's avatar
Fedor Sakharov committed
36
37
38
39
40
41
};
use runtime_parachains::{
	self,
	runtime_api_impl::v1 as runtime_api_impl,
};
use frame_support::{
42
43
44
	construct_runtime, parameter_types,
	traits::{EnsureOrigin, Filter, KeyOwnerProofSystem, Randomness},
	weights::Weight,
Fedor Sakharov's avatar
Fedor Sakharov committed
45
46
47
};
use sp_runtime::{
	create_runtime_str, generic, impl_opaque_keys,
48
	ApplyExtrinsicResult, KeyTypeId, Perbill,
Fedor Sakharov's avatar
Fedor Sakharov committed
49
50
	transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority},
	traits::{
51
		BlakeTwo256, Block as BlockT, OpaqueKeys, AccountIdLookup,
Fedor Sakharov's avatar
Fedor Sakharov committed
52
53
54
		Extrinsic as ExtrinsicT, SaturatedConversion, Verify,
	},
};
55
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
Fedor Sakharov's avatar
Fedor Sakharov committed
56
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
57
58
#[cfg(any(feature = "std", test))]
use sp_version::NativeVersion;
59
use sp_version::RuntimeVersion;
60
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
61
use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives};
Fedor Sakharov's avatar
Fedor Sakharov committed
62
63
use sp_core::OpaqueMetadata;
use sp_staking::SessionIndex;
64
use pallet_session::historical as session_historical;
65
use frame_system::{EnsureRoot, EnsureOneOf, EnsureSigned};
Shaun Wang's avatar
Shaun Wang committed
66
use runtime_common::{paras_sudo_wrapper, paras_registrar, xcm_sender};
Fedor Sakharov's avatar
Fedor Sakharov committed
67

68
use runtime_parachains::origin as parachains_origin;
Fedor Sakharov's avatar
Fedor Sakharov committed
69
use runtime_parachains::configuration as parachains_configuration;
70
use runtime_parachains::shared as parachains_shared;
Fedor Sakharov's avatar
Fedor Sakharov committed
71
72
73
use runtime_parachains::inclusion as parachains_inclusion;
use runtime_parachains::inclusion_inherent as parachains_inclusion_inherent;
use runtime_parachains::initializer as parachains_initializer;
74
use runtime_parachains::session_info as parachains_session_info;
Fedor Sakharov's avatar
Fedor Sakharov committed
75
use runtime_parachains::paras as parachains_paras;
76
77
78
use runtime_parachains::dmp as parachains_dmp;
use runtime_parachains::ump as parachains_ump;
use runtime_parachains::hrmp as parachains_hrmp;
Fedor Sakharov's avatar
Fedor Sakharov committed
79
80
use runtime_parachains::scheduler as parachains_scheduler;

81
pub use pallet_balances::Call as BalancesCall;
Fedor Sakharov's avatar
Fedor Sakharov committed
82

Shawn Tabrizi's avatar
Shawn Tabrizi committed
83
84
85
86
87
88
89
90
use polkadot_parachain::primitives::Id as ParaId;
use xcm::v0::{MultiLocation, NetworkId};
use xcm_executor::traits::IsConcrete;
use xcm_builder::{
	AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation,
	CurrencyAdapter as XcmCurrencyAdapter, ChildParachainAsNative,
	SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter,
};
91
use constants::{time::*, currency::*, fee::*};
Shawn Tabrizi's avatar
Shawn Tabrizi committed
92

Fedor Sakharov's avatar
Fedor Sakharov committed
93
94
/// Constant values used within the runtime.
pub mod constants;
95
mod propose_parachain;
Fedor Sakharov's avatar
Fedor Sakharov committed
96
97
98
99
100

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

101
102
103
/// Runtime version (Rococo).
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("rococo"),
Bastian Köcher's avatar
Bastian Köcher committed
104
	impl_name: create_runtime_str!("parity-rococo-v1-1"),
105
	authoring_version: 0,
Bastian Köcher's avatar
Bastian Köcher committed
106
	spec_version: 210,
107
108
109
110
111
112
113
114
	impl_version: 0,
	#[cfg(not(feature = "disable-runtime-api"))]
	apis: RUNTIME_API_VERSIONS,
	#[cfg(feature = "disable-runtime-api")]
	apis: sp_version::create_apis_vec![[]],
	transaction_version: 0,
};

115
116
117
118
119
120
121
/// 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
	};

122
123
124
125
126
127
128
129
130
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
	NativeVersion {
		runtime_version: VERSION,
		can_author_with: Default::default(),
	}
}

Fedor Sakharov's avatar
Fedor Sakharov committed
131
/// The address format for describing accounts.
132
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
Fedor Sakharov's avatar
Fedor Sakharov committed
133
134
135
136
137
138
139
140
141
142
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// A Block signed with a Justification
pub type SignedBlock = generic::SignedBlock<Block>;
/// BlockId type as expected by this runtime.
pub type BlockId = generic::BlockId<Block>;
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
143
144
145
146
147
148
149
	frame_system::CheckSpecVersion<Runtime>,
	frame_system::CheckTxVersion<Runtime>,
	frame_system::CheckGenesis<Runtime>,
	frame_system::CheckMortality<Runtime>,
	frame_system::CheckNonce<Runtime>,
	frame_system::CheckWeight<Runtime>,
	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
Fedor Sakharov's avatar
Fedor Sakharov committed
150
151
152
153
154
155
156
);

/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
/// Extrinsic type that has already been checked.
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
/// Executive: handles dispatch to the various modules.
157
pub type Executive = frame_executive::Executive<Runtime, Block, frame_system::ChainContext<Runtime>, Runtime, AllModules>;
Fedor Sakharov's avatar
Fedor Sakharov committed
158
159
160
161
162
/// The payload being signed in transactions.
pub type SignedPayload = generic::SignedPayload<Call, SignedExtra>;

impl_opaque_keys! {
	pub struct SessionKeys {
163
		pub grandpa: Grandpa,
Fedor Sakharov's avatar
Fedor Sakharov committed
164
165
		pub babe: Babe,
		pub im_online: ImOnline,
166
167
		pub para_validator: Initializer,
		pub para_assignment: SessionInfo,
168
		pub authority_discovery: AuthorityDiscovery,
Fedor Sakharov's avatar
Fedor Sakharov committed
169
170
171
172
173
174
175
176
177
	}
}

construct_runtime! {
	pub enum Runtime where
		Block = Block,
		NodeBlock = primitives::v1::Block,
		UncheckedExtrinsic = UncheckedExtrinsic
	{
178
		System: frame_system::{Module, Call, Storage, Config, Event<T>},
Fedor Sakharov's avatar
Fedor Sakharov committed
179
180

		// Must be before session.
181
		Babe: pallet_babe::{Module, Call, Storage, Config, ValidateUnsigned},
Fedor Sakharov's avatar
Fedor Sakharov committed
182

183
184
185
186
		Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
		Indices: pallet_indices::{Module, Call, Storage, Config<T>, Event<T>},
		Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
		TransactionPayment: pallet_transaction_payment::{Module, Storage},
Fedor Sakharov's avatar
Fedor Sakharov committed
187
188

		// Consensus support.
189
190
		Authorship: pallet_authorship::{Module, Call, Storage},
		Offences: pallet_offences::{Module, Call, Storage, Event},
Fedor Sakharov's avatar
Fedor Sakharov committed
191
		Historical: session_historical::{Module},
192
193
194
195
		Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
		Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event, ValidateUnsigned},
		ImOnline: pallet_im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
		AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config},
Fedor Sakharov's avatar
Fedor Sakharov committed
196
197

		// Parachains modules.
198
199
		ParachainsOrigin: parachains_origin::{Module, Origin},
		ParachainsConfiguration: parachains_configuration::{Module, Call, Storage, Config<T>},
200
		Shared: parachains_shared::{Module, Call, Storage},
Fedor Sakharov's avatar
Fedor Sakharov committed
201
		Inclusion: parachains_inclusion::{Module, Call, Storage, Event<T>},
202
		InclusionInherent: parachains_inclusion_inherent::{Module, Call, Storage, Inherent},
Fedor Sakharov's avatar
Fedor Sakharov committed
203
		Scheduler: parachains_scheduler::{Module, Call, Storage},
204
205
		Paras: parachains_paras::{Module, Call, Storage},
		Initializer: parachains_initializer::{Module, Call, Storage},
206
207
		Dmp: parachains_dmp::{Module, Call, Storage},
		Ump: parachains_ump::{Module, Call, Storage},
208
		Hrmp: parachains_hrmp::{Module, Call, Storage, Event},
209
		SessionInfo: parachains_session_info::{Module, Call, Storage},
Fedor Sakharov's avatar
Fedor Sakharov committed
210

211
212
213
214
215
		Registrar: paras_registrar::{Module, Call, Storage},
		ParasSudoWrapper: paras_sudo_wrapper::{Module, Call},

		// Sudo
		Sudo: pallet_sudo::{Module, Call, Storage, Event<T>, Config<T>},
216
217

		// Propose parachain pallet.
Ricardo Rius's avatar
Ricardo Rius committed
218
		ProposeParachain: propose_parachain::{Module, Call, Storage, Event<T>},
219
220
221
	}
}

222
223
224
225
226
227
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
	fn filter(_call: &Call) -> bool {
		true
	}
}
228

Fedor Sakharov's avatar
Fedor Sakharov committed
229
230
parameter_types! {
	pub const Version: RuntimeVersion = VERSION;
231
	pub const SS58Prefix: u8 = 42;
Fedor Sakharov's avatar
Fedor Sakharov committed
232
233
}

234
impl frame_system::Config for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
235
	type BaseCallFilter = BaseFilter;
236
237
238
	type BlockWeights = BlockWeights;
	type BlockLength = BlockLength;
	type DbWeight = RocksDbWeight;
Fedor Sakharov's avatar
Fedor Sakharov committed
239
240
241
242
243
244
245
	type Origin = Origin;
	type Call = Call;
	type Index = Nonce;
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
246
	type Lookup = AccountIdLookup<AccountId, ()>;
Fedor Sakharov's avatar
Fedor Sakharov committed
247
248
249
250
	type Header = generic::Header<BlockNumber, BlakeTwo256>;
	type Event = Event;
	type BlockHashCount = BlockHashCount;
	type Version = Version;
251
	type PalletInfo = PalletInfo;
252
	type AccountData = pallet_balances::AccountData<Balance>;
Fedor Sakharov's avatar
Fedor Sakharov committed
253
254
255
	type OnNewAccount = ();
	type OnKilledAccount = ();
	type SystemWeightInfo = ();
256
	type SS58Prefix = SS58Prefix;
Fedor Sakharov's avatar
Fedor Sakharov committed
257
258
259
260
261
262
263
264
265
266
267
268
}

parameter_types! {
	pub const MaxCodeSize: u32 = 10 * 1024 * 1024; // 10 MB
	pub const MaxHeadDataSize: u32 = 20 * 1024; // 20 KB
	pub const ValidationUpgradeFrequency: BlockNumber = 2 * DAYS;
	pub const ValidationUpgradeDelay: BlockNumber = 8 * HOURS;
	pub const SlashPeriod: BlockNumber = 7 * DAYS;
}

/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
/// format of the chain.
269
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime where
Fedor Sakharov's avatar
Fedor Sakharov committed
270
271
	Call: From<LocalCall>,
{
272
	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
Fedor Sakharov's avatar
Fedor Sakharov committed
273
274
275
		call: Call,
		public: <Signature as Verify>::Signer,
		account: AccountId,
276
		nonce: <Runtime as frame_system::Config>::Index,
Fedor Sakharov's avatar
Fedor Sakharov committed
277
	) -> Option<(Call, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
278
		use sp_runtime::traits::StaticLookup;
Fedor Sakharov's avatar
Fedor Sakharov committed
279
280
281
282
283
284
285
286
287
288
289
290
291
		// take the biggest period possible.
		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>()
			// The `System::block_number` is initialized with `n+1`,
			// so the actual block number is `n`.
			.saturating_sub(1);
		let tip = 0;
		let extra: SignedExtra = (
292
293
294
295
296
297
298
			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),
Fedor Sakharov's avatar
Fedor Sakharov committed
299
300
		);
		let raw_payload = SignedPayload::new(call, extra).map_err(|e| {
301
			log::warn!("Unable to create signed payload: {:?}", e);
Fedor Sakharov's avatar
Fedor Sakharov committed
302
303
304
305
306
		}).ok()?;
		let signature = raw_payload.using_encoded(|payload| {
			C::sign(payload, public)
		})?;
		let (call, extra, _) = raw_payload.deconstruct();
307
308
		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
		Some((call, (address, signature, extra)))
Fedor Sakharov's avatar
Fedor Sakharov committed
309
310
311
	}
}

312
impl frame_system::offchain::SigningTypes for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
313
314
315
316
	type Public = <Signature as Verify>::Signer;
	type Signature = Signature;
}

317
318
319
320
/// Special `FullIdentificationOf` implementation that is returning for every input `Some(Default::default())`.
pub struct FullIdentificationOf;
impl sp_runtime::traits::Convert<AccountId, Option<()>> for FullIdentificationOf {
	fn convert(_: AccountId) -> Option<()> { Some(Default::default()) }
Fedor Sakharov's avatar
Fedor Sakharov committed
321
322
}

323
324
325
impl pallet_session::historical::Config for Runtime {
	type FullIdentification = ();
	type FullIdentificationOf = FullIdentificationOf;
Fedor Sakharov's avatar
Fedor Sakharov committed
326
327
328
}

parameter_types! {
329
	pub SessionDuration: BlockNumber = EpochDurationInBlocks::get() as _;
Fedor Sakharov's avatar
Fedor Sakharov committed
330
331
332
333
334
335
336
}

parameter_types! {
	pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
	pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
}

337
impl pallet_im_online::Config for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
338
339
	type AuthorityId = ImOnlineId;
	type Event = Event;
340
	type ValidatorSet = Historical;
Fedor Sakharov's avatar
Fedor Sakharov committed
341
342
343
344
345
346
347
348
	type ReportUnresponsiveness = Offences;
	type SessionDuration = SessionDuration;
	type UnsignedPriority = StakingUnsignedPriority;
	type WeightInfo = ();
}

parameter_types! {
	pub const ExistentialDeposit: Balance = 1 * CENTS;
349
	pub const MaxLocks: u32 = 50;
Fedor Sakharov's avatar
Fedor Sakharov committed
350
351
}

352
impl pallet_balances::Config for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
353
354
355
356
357
	type Balance = Balance;
	type DustRemoval = ();
	type Event = Event;
	type ExistentialDeposit = ExistentialDeposit;
	type AccountStore = System;
358
	type MaxLocks = MaxLocks;
Fedor Sakharov's avatar
Fedor Sakharov committed
359
360
361
	type WeightInfo = ();
}

362
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where
Fedor Sakharov's avatar
Fedor Sakharov committed
363
364
365
366
367
368
369
370
371
372
373
374
375
	Call: From<C>,
{
	type OverarchingCall = Call;
	type Extrinsic = UncheckedExtrinsic;
}

parameter_types! {
	pub const ParathreadDeposit: Balance = 5 * DOLLARS;
	pub const QueueSize: usize = 2;
	pub const MaxRetries: u32 = 3;
}

parameter_types! {
376
	pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * BlockWeights::get().max_block;
Fedor Sakharov's avatar
Fedor Sakharov committed
377
378
}

379
impl pallet_offences::Config for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
380
	type Event = Event;
381
	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
382
	type OnOffenceHandler = ();
Fedor Sakharov's avatar
Fedor Sakharov committed
383
384
385
	type WeightSoftLimit = OffencesWeightSoftLimit;
}

386
impl pallet_authority_discovery::Config for Runtime {}
Fedor Sakharov's avatar
Fedor Sakharov committed
387
388
389
390

parameter_types! {
	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
}
391
impl pallet_timestamp::Config for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
392
393
394
395
396
397
398
399
400
401
	type Moment = u64;
	type OnTimestampSet = Babe;
	type MinimumPeriod = MinimumPeriod;
	type WeightInfo = ();
}

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

402
impl pallet_transaction_payment::Config for Runtime {
Albrecht's avatar
Albrecht committed
403
	type OnChargeTransaction = CurrencyAdapter<Balances, ToAuthor<Runtime>>;
Fedor Sakharov's avatar
Fedor Sakharov committed
404
405
406
407
408
409
410
411
412
	type TransactionByteFee = TransactionByteFee;
	type WeightToFee = WeightToFee;
	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
}

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

413
414
415
416
417
418
/// Special `ValidatorIdOf` implementation that is just returning the input as result.
pub struct ValidatorIdOf;
impl sp_runtime::traits::Convert<AccountId, Option<AccountId>> for ValidatorIdOf {
	fn convert(a: AccountId) -> Option<AccountId> { Some(a) }
}

419
impl pallet_session::Config for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
420
421
	type Event = Event;
	type ValidatorId = AccountId;
422
	type ValidatorIdOf = ValidatorIdOf;
Fedor Sakharov's avatar
Fedor Sakharov committed
423
424
	type ShouldEndSession = Babe;
	type NextSessionRotation = Babe;
425
	type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, ProposeParachain>;
Fedor Sakharov's avatar
Fedor Sakharov committed
426
427
428
429
430
431
432
433
	type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
	type Keys = SessionKeys;
	type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
	type WeightInfo = ();
}

parameter_types! {
	pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
434
	pub ReportLongevity: u64 = EpochDurationInBlocks::get() as u64 * 10;
Fedor Sakharov's avatar
Fedor Sakharov committed
435
436
}

437
impl pallet_babe::Config for Runtime {
438
	type EpochDuration = EpochDurationInBlocks;
Fedor Sakharov's avatar
Fedor Sakharov committed
439
440
441
	type ExpectedBlockTime = ExpectedBlockTime;

	// session module is the trigger
442
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
Fedor Sakharov's avatar
Fedor Sakharov committed
443
444
445
446
447

	type KeyOwnerProofSystem = Historical;

	type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
448
		pallet_babe::AuthorityId,
Fedor Sakharov's avatar
Fedor Sakharov committed
449
450
451
452
	)>>::Proof;

	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
453
		pallet_babe::AuthorityId,
Fedor Sakharov's avatar
Fedor Sakharov committed
454
455
456
	)>>::IdentificationTuple;

	type HandleEquivocation =
457
		pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
458
459

	type WeightInfo = ();
Fedor Sakharov's avatar
Fedor Sakharov committed
460
461
462
463
464
465
}

parameter_types! {
	pub const IndexDeposit: Balance = 1 * DOLLARS;
}

466
impl pallet_indices::Config for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
467
468
469
470
471
472
473
474
475
476
477
	type AccountIndex = AccountIndex;
	type Currency = Balances;
	type Deposit = IndexDeposit;
	type Event = Event;
	type WeightInfo = ();
}

parameter_types! {
	pub const AttestationPeriod: BlockNumber = 50;
}

478
impl pallet_grandpa::Config for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
479
480
481
482
483
484
485
486
487
488
489
490
491
	type Event = Event;
	type Call = Call;

	type KeyOwnerProofSystem = Historical;

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

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

492
493
	type HandleEquivocation =
		pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
494
495

	type WeightInfo = ();
Fedor Sakharov's avatar
Fedor Sakharov committed
496
497
498
499
500
501
502
}

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

// TODO: substrate#2986 implement this properly
503
impl pallet_authorship::Config for Runtime {
504
	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
Fedor Sakharov's avatar
Fedor Sakharov committed
505
506
	type UncleGenerations = UncleGenerations;
	type FilterUncle = ();
507
	type EventHandler = ImOnline;
Fedor Sakharov's avatar
Fedor Sakharov committed
508
509
}

510
impl parachains_origin::Config for Runtime {}
511

512
impl parachains_configuration::Config for Runtime {}
Fedor Sakharov's avatar
Fedor Sakharov committed
513

514
515
impl parachains_shared::Config for Runtime {}

516
517
518
519
520
521
522
/// Special `RewardValidators` that does nothing ;)
pub struct RewardValidators;
impl runtime_parachains::inclusion::RewardValidators for RewardValidators {
	fn reward_backing(_: impl IntoIterator<Item=ValidatorIndex>) {}
	fn reward_bitfields(_: impl IntoIterator<Item=ValidatorIndex>) {}
}

523
impl parachains_inclusion::Config for Runtime {
Fedor Sakharov's avatar
Fedor Sakharov committed
524
	type Event = Event;
525
	type RewardValidators = RewardValidators;
Fedor Sakharov's avatar
Fedor Sakharov committed
526
527
}

528
impl parachains_paras::Config for Runtime {
529
530
	type Origin = Origin;
}
Fedor Sakharov's avatar
Fedor Sakharov committed
531

Shawn Tabrizi's avatar
Shawn Tabrizi committed
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
parameter_types! {
	pub const RocLocation: MultiLocation = MultiLocation::Null;
	pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
	pub const Ancestry: MultiLocation = MultiLocation::Null;
}

pub type LocationConverter = (
	ChildParachainConvertsVia<ParaId, AccountId>,
	AccountId32Aliases<RococoNetwork, 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<RocLocation>,
		// 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,
	>;

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

pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
	type Call = Call;
Shaun Wang's avatar
Shaun Wang committed
565
	type XcmSender = xcm_sender::RelayChainXcmSender<Runtime>;
Shawn Tabrizi's avatar
Shawn Tabrizi committed
566
567
568
569
570
571
572
	type AssetTransactor = LocalAssetTransactor;
	type OriginConverter = LocalOriginConverter;
	type IsReserve = ();
	type IsTeleporter = ();
	type LocationInverter = LocationInverter<Ancestry>;
}

573
impl parachains_session_info::Config for Runtime {}
574

575
impl parachains_ump::Config for Runtime {
Shawn Tabrizi's avatar
Shawn Tabrizi committed
576
	type UmpSink = crate::parachains_ump::XcmSink<XcmConfig>;
577
}
578

579
impl parachains_dmp::Config for Runtime {}
580

581
impl parachains_hrmp::Config for Runtime {
582
	type Event = Event;
583
	type Origin = Origin;
584
	type Currency = Balances;
585
586
}

587
impl parachains_inclusion_inherent::Config for Runtime {}
Fedor Sakharov's avatar
Fedor Sakharov committed
588

589
impl parachains_scheduler::Config for Runtime {}
Fedor Sakharov's avatar
Fedor Sakharov committed
590

591
impl parachains_initializer::Config for Runtime {
592
	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
Fedor Sakharov's avatar
Fedor Sakharov committed
593
}
594

595
impl paras_sudo_wrapper::Config for Runtime {}
596

597
impl paras_registrar::Config for Runtime {
598
599
600
601
	type Currency = Balances;
	type ParathreadDeposit = ParathreadDeposit;
	type Origin = Origin;
}
602

603
impl pallet_sudo::Config for Runtime {
604
605
606
607
	type Event = Event;
	type Call = Call;
}

608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
/// Priviledged origin used by propose parachain.
pub struct PriviledgedOrigin;

impl EnsureOrigin<Origin> for PriviledgedOrigin {
	type Success = ();

	fn try_origin(o: Origin) -> Result<Self::Success, Origin> {
		let allowed = [
			hex_literal::hex!("b44c58e50328768ac06ed44b842bfa69d86ea10f60bc36156c9ffc5e00867220"),
			hex_literal::hex!("762a6a38ba72b139cba285a39a6766e02046fb023f695f5ecf7f48b037c0dd6b")
		];

		let origin = o.clone();
		match EnsureSigned::try_origin(o) {
			Ok(who) if allowed.iter().any(|a| a == &who.as_ref()) => Ok(()),
			_ => Err(origin),
		}
	}

	#[cfg(feature = "runtime-benchmarks")]
	fn successful_origin() -> Origin { Origin::root() }
}

parameter_types! {
	pub const ProposeDeposit: Balance = 1000 * DOLLARS;
	pub const MaxNameLength: u32 = 20;
}

impl propose_parachain::Config for Runtime {
	type Event = Event;
	type MaxNameLength = MaxNameLength;
	type ProposeDeposit = ProposeDeposit;
	type PriviledgedOrigin = EnsureOneOf<AccountId, EnsureRoot<AccountId>, PriviledgedOrigin>;
}

643
644
645
646
647
648
649
650
#[cfg(not(feature = "disable-runtime-api"))]
sp_api::impl_runtime_apis! {
	impl sp_api::Core<Block> for Runtime {
		fn version() -> RuntimeVersion {
			VERSION
		}

		fn execute_block(block: Block) {
651
			Executive::execute_block(block);
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
		}

		fn initialize_block(header: &<Block as BlockT>::Header) {
			Executive::initialize_block(header)
		}
	}

	impl sp_api::Metadata<Block> for Runtime {
		fn metadata() -> OpaqueMetadata {
			Runtime::metadata().into()
		}
	}

	impl block_builder_api::BlockBuilder<Block> for Runtime {
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
			Executive::apply_extrinsic(extrinsic)
		}

		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
		}

		fn inherent_extrinsics(data: inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
			data.create_extrinsics()
		}

		fn check_inherents(
			block: Block,
			data: inherents::InherentData,
		) -> inherents::CheckInherentsResult {
			data.check_extrinsics(&block)
		}

		fn random_seed() -> <Block as BlockT>::Hash {
686
			pallet_babe::RandomnessFromOneEpochAgo::<Runtime>::random_seed().0
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
		}
	}

	impl tx_pool_api::runtime_api::TaggedTransactionQueue<Block> for Runtime {
		fn validate_transaction(
			source: TransactionSource,
			tx: <Block as BlockT>::Extrinsic,
		) -> TransactionValidity {
			Executive::validate_transaction(source, tx)
		}
	}

	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
		fn offchain_worker(header: &<Block as BlockT>::Header) {
			Executive::offchain_worker(header)
		}
	}

	impl primitives::v1::ParachainHost<Block, Hash, BlockNumber> for Runtime {
		fn validators() -> Vec<ValidatorId> {
			runtime_api_impl::validators::<Runtime>()
		}

		fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
			runtime_api_impl::validator_groups::<Runtime>()
		}

714
		fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
715
716
717
718
719
720
721
722
723
724
			runtime_api_impl::availability_cores::<Runtime>()
		}

		fn persisted_validation_data(para_id: Id, assumption: OccupiedCoreAssumption)
			-> Option<PersistedValidationData<BlockNumber>> {
			runtime_api_impl::persisted_validation_data::<Runtime>(para_id, assumption)
		}

		fn check_validation_outputs(
			para_id: Id,
725
			outputs: primitives::v1::CandidateCommitments,
726
727
728
729
730
731
732
733
734
735
736
737
738
		) -> bool {
			runtime_api_impl::check_validation_outputs::<Runtime>(para_id, outputs)
		}

		fn session_index_for_child() -> SessionIndex {
			runtime_api_impl::session_index_for_child::<Runtime>()
		}

		fn validation_code(para_id: Id, assumption: OccupiedCoreAssumption)
			-> Option<ValidationCode> {
			runtime_api_impl::validation_code::<Runtime>(para_id, assumption)
		}

739
740
741
742
743
744
		fn historical_validation_code(para_id: Id, context_height: BlockNumber)
			-> Option<ValidationCode>
		{
			runtime_api_impl::historical_validation_code::<Runtime>(para_id, context_height)
		}

745
746
747
748
749
750
751
752
753
754
755
756
757
758
		fn candidate_pending_availability(para_id: Id) -> Option<CommittedCandidateReceipt<Hash>> {
			runtime_api_impl::candidate_pending_availability::<Runtime>(para_id)
		}

		fn candidate_events() -> Vec<CandidateEvent<Hash>> {
			runtime_api_impl::candidate_events::<Runtime, _>(|ev| {
				match ev {
					Event::parachains_inclusion(ev) => {
						Some(ev)
					}
					_ => None,
				}
			})
		}
759

760
		fn session_info(index: SessionIndex) -> Option<SessionInfoData> {
761
			runtime_api_impl::session_info::<Runtime>(index)
762
763
		}

Sergey Pepyakin's avatar
Sergey Pepyakin committed
764
		fn dmq_contents(recipient: Id) -> Vec<InboundDownwardMessage<BlockNumber>> {
765
766
			runtime_api_impl::dmq_contents::<Runtime>(recipient)
		}
Sergey Pepyakin's avatar
Sergey Pepyakin committed
767
768
769
770
771
772

		fn inbound_hrmp_channels_contents(
			recipient: Id
		) -> BTreeMap<Id, Vec<InboundHrmpMessage<BlockNumber>>> {
			runtime_api_impl::inbound_hrmp_channels_contents::<Runtime>(recipient)
		}
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
	}

	impl fg_primitives::GrandpaApi<Block> for Runtime {
		fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
			Grandpa::grandpa_authorities()
		}

		fn submit_report_equivocation_unsigned_extrinsic(
			equivocation_proof: fg_primitives::EquivocationProof<
				<Block as BlockT>::Hash,
				sp_runtime::traits::NumberFor<Block>,
			>,
			key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
		) -> Option<()> {
			let key_owner_proof = key_owner_proof.decode()?;

			Grandpa::submit_unsigned_equivocation_report(
				equivocation_proof,
				key_owner_proof,
			)
		}

		fn generate_key_ownership_proof(
			_set_id: fg_primitives::SetId,
			authority_id: fg_primitives::AuthorityId,
		) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
799
			use parity_scale_codec::Encode;
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

			Historical::prove((fg_primitives::KEY_TYPE, authority_id))
				.map(|p| p.encode())
				.map(fg_primitives::OpaqueKeyOwnershipProof::new)
		}
	}

	impl babe_primitives::BabeApi<Block> for Runtime {
		fn configuration() -> babe_primitives::BabeGenesisConfiguration {
			// The choice of `c` parameter (where `1 - c` represents the
			// probability of a slot being empty), is done in accordance to the
			// slot duration and expected target block time, for safely
			// resisting network delays of maximum two seconds.
			// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
			babe_primitives::BabeGenesisConfiguration {
				slot_duration: Babe::slot_duration(),
816
				epoch_length: EpochDurationInBlocks::get().into(),
817
				c: BABE_GENESIS_EPOCH_CONFIG.c,
818
819
				genesis_authorities: Babe::authorities(),
				randomness: Babe::randomness(),
820
				allowed_slots: BABE_GENESIS_EPOCH_CONFIG.allowed_slots,
821
822
823
			}
		}

Bastian Köcher's avatar
Bastian Köcher committed
824
		fn current_epoch_start() -> babe_primitives::Slot {
825
826
827
			Babe::current_epoch_start()
		}

828
829
830
831
		fn current_epoch() -> babe_primitives::Epoch {
			Babe::current_epoch()
		}

832
833
834
835
		fn next_epoch() -> babe_primitives::Epoch {
			Babe::next_epoch()
		}

836
		fn generate_key_ownership_proof(
Bastian Köcher's avatar
Bastian Köcher committed
837
			_slot: babe_primitives::Slot,
838
839
			authority_id: babe_primitives::AuthorityId,
		) -> Option<babe_primitives::OpaqueKeyOwnershipProof> {
840
			use parity_scale_codec::Encode;
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861

			Historical::prove((babe_primitives::KEY_TYPE, authority_id))
				.map(|p| p.encode())
				.map(babe_primitives::OpaqueKeyOwnershipProof::new)
		}

		fn submit_report_equivocation_unsigned_extrinsic(
			equivocation_proof: babe_primitives::EquivocationProof<<Block as BlockT>::Header>,
			key_owner_proof: babe_primitives::OpaqueKeyOwnershipProof,
		) -> Option<()> {
			let key_owner_proof = key_owner_proof.decode()?;

			Babe::submit_unsigned_equivocation_report(
				equivocation_proof,
				key_owner_proof,
			)
		}
	}

	impl authority_discovery_primitives::AuthorityDiscoveryApi<Block> for Runtime {
		fn authorities() -> Vec<AuthorityDiscoveryId> {
862
			runtime_api_impl::relevant_authority_ids::<Runtime>()
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
		}
	}

	impl sp_session::SessionKeys<Block> for Runtime {
		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
			SessionKeys::generate(seed)
		}

		fn decode_session_keys(
			encoded: Vec<u8>,
		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
			SessionKeys::decode_into_raw_public_keys(&encoded)
		}
	}

	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
		fn account_nonce(account: AccountId) -> Nonce {
			System::account_nonce(account)
		}
	}

	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
		Block,
		Balance,
	> for Runtime {
		fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_info(uxt, len)
		}
891
892
893
		fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {
			TransactionPayment::query_fee_details(uxt, len)
		}
894
895
	}
}