git.delta.rocks / unique-network / refs/commits / a931d82a9899

difftreelog

feat(collator-selection) opal only

Fahrrader2022-10-28parent: #3858e94.patch.diff
in: master

10 files changed

modifiednode/cli/src/chain_spec.rsdiffbeforeafterboth
--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -24,7 +24,7 @@
 use serde_json::map::Map;
 
 use up_common::types::opaque::*;
-use up_common::constants::EXISTENTIAL_DEPOSIT;
+use up_common::constants::CANDIDACY_BOND;
 
 #[cfg(feature = "unique-runtime")]
 pub use unique_runtime as default_runtime;
@@ -151,6 +151,7 @@
 	AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
 }
 
+#[cfg(not(any(feature = "unique-runtime", feature = "quartz-runtime")))]
 macro_rules! testnet_genesis {
 	(
 		$runtime:path,
@@ -191,7 +192,7 @@
 					.cloned()
 					.map(|(acc, _)| acc)
 					.collect(),
-				candidacy_bond: EXISTENTIAL_DEPOSIT * 16,
+				candidacy_bond: CANDIDACY_BOND,
 				..Default::default()
 			},
 			session: SessionConfig {
@@ -207,9 +208,6 @@
 					.collect(),
 			},
 			aura: Default::default(),
-			/*aura: AuraConfig {
-				authorities: $initial_authorities,
-			},*/
 			aura_ext: Default::default(),
 			evm: EVMConfig {
 				accounts: BTreeMap::new(),
@@ -219,6 +217,56 @@
 	}};
 }
 
+#[cfg(any(feature = "unique-runtime", feature = "quartz-runtime"))]
+macro_rules! testnet_genesis {
+	(
+		$runtime:path,
+		$root_key:expr,
+		$initial_invulnerables:expr,
+		$endowed_accounts:expr,
+		$id:expr
+	) => {{
+		use $runtime::*;
+
+		GenesisConfig {
+			system: SystemConfig {
+				code: WASM_BINARY
+					.expect("WASM binary was not build, please build it!")
+					.to_vec(),
+			},
+			balances: BalancesConfig {
+				balances: $endowed_accounts
+					.iter()
+					.cloned()
+					// 1e13 UNQ
+					.map(|k| (k, 1 << 100))
+					.collect(),
+			},
+			treasury: Default::default(),
+			tokens: TokensConfig { balances: vec![] },
+			sudo: SudoConfig {
+				key: Some($root_key),
+			},
+			vesting: VestingConfig { vesting: vec![] },
+			parachain_info: ParachainInfoConfig {
+				parachain_id: $id.into(),
+			},
+			parachain_system: Default::default(),
+			aura: AuraConfig {
+				authorities: $initial_invulnerables
+					.into_iter()
+					.map(|(_, aura)| aura)
+					.collect(),
+			},
+			aura_ext: Default::default(),
+			evm: EVMConfig {
+				accounts: BTreeMap::new(),
+			},
+			ethereum: EthereumConfig {},
+		}
+	}};
+}
+
 pub fn development_config() -> DefaultChainSpec {
 	let mut properties = Map::new();
 	properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());
modifiedprimitives/common/src/constants.rsdiffbeforeafterboth
--- a/primitives/common/src/constants.rs
+++ b/primitives/common/src/constants.rs
@@ -41,7 +41,10 @@
 pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE;
 pub const UNIQUE: Balance = 100 * CENTIUNIQUE;
 
+/// Minimum balance required to create or keep an account open.
 pub const EXISTENTIAL_DEPOSIT: u128 = 0;
+/// Amount of Balance reserved for candidate registration.
+pub const CANDIDACY_BOND: u128 = EXISTENTIAL_DEPOSIT;
 
 // Targeting 0.1 UNQ per transfer
 pub const WEIGHT_TO_FEE_COEFF: u32 = /*<weight2fee>*/207_163_598/*</weight2fee>*/;
addedruntime/common/config/pallets/collator_selection.rsdiffbeforeafterboth
--- /dev/null
+++ b/runtime/common/config/pallets/collator_selection.rs
@@ -0,0 +1,78 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network 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.
+
+// Unique Network 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 Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+use frame_support::{parameter_types, PalletId};
+use frame_system::EnsureRoot;
+use crate::{
+	AccountId, BlockNumber, Runtime, RuntimeEvent, Balances, Aura, Session, SessionKeys,
+	CollatorSelection,
+};
+use up_common::constants::*;
+
+parameter_types! {
+	pub const SessionPeriod: BlockNumber = HOURS;
+	pub const SessionOffset: BlockNumber = 0;
+}
+
+impl pallet_session::Config for Runtime {
+	type RuntimeEvent = RuntimeEvent;
+	type ValidatorId = <Self as frame_system::Config>::AccountId;
+	// we don't have stash and controller, thus we don't need the convert as well.
+	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
+	type ShouldEndSession = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
+	type NextSessionRotation = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
+	type SessionManager = CollatorSelection;
+	// Essentially just Aura, but lets be pedantic.
+	type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
+	type Keys = SessionKeys;
+	type WeightInfo = pallet_session::weights::SubstrateWeight<Self>; // ();
+}
+
+parameter_types! {
+	pub const UncleGenerations: u32 = 0;
+}
+
+impl pallet_authorship::Config for Runtime {
+	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
+	type UncleGenerations = UncleGenerations;
+	type FilterUncle = ();
+	type EventHandler = CollatorSelection;
+}
+
+parameter_types! {
+	pub const PotId: PalletId = PalletId(*b"PotStake");
+	pub const MaxCandidates: u32 = 1000;
+	pub const MinCandidates: u32 = 5;
+	pub const MaxInvulnerables: u32 = 100;
+}
+
+impl pallet_collator_selection::Config for Runtime {
+	type RuntimeEvent = RuntimeEvent;
+	type Currency = Balances;
+	// We allow root only to execute privileged collator selection operations.
+	type UpdateOrigin = EnsureRoot<AccountId>;
+	type PotId = PotId;
+	type MaxCandidates = MaxCandidates;
+	type MinCandidates = MinCandidates;
+	type MaxInvulnerables = MaxInvulnerables;
+	// todo:collator kick threshold should be in storage and configured only by root -- or rather UpdateOrigin
+	// Should be a multiple of session or things will get inconsistent.
+	type KickThreshold = SessionPeriod;
+	type ValidatorId = <Self as frame_system::Config>::AccountId;
+	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
+	type ValidatorRegistration = Session;
+	type WeightInfo = ();
+}
modifiedruntime/common/config/pallets/mod.rsdiffbeforeafterboth
--- a/runtime/common/config/pallets/mod.rs
+++ b/runtime/common/config/pallets/mod.rs
@@ -46,6 +46,9 @@
 #[cfg(feature = "app-promotion")]
 pub mod app_promotion;
 
+#[cfg(feature = "collator-selection")]
+pub mod collator_selection;
+
 parameter_types! {
 	pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
 	pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
modifiedruntime/common/config/substrate.rsdiffbeforeafterboth
--- a/runtime/common/config/substrate.rs
+++ b/runtime/common/config/substrate.rs
@@ -34,7 +34,7 @@
 };
 use crate::{
 	runtime_common::DealWithFees, Runtime, RuntimeEvent, RuntimeCall, RuntimeOrigin, PalletInfo,
-	System, Balances, Treasury, SS58Prefix, Aura, Session, SessionKeys, CollatorSelection, Version,
+	System, Balances, Treasury, SS58Prefix, Version,
 };
 use up_common::{types::*, constants::*};
 
@@ -215,58 +215,4 @@
 	type AuthorityId = AuraId;
 	type DisabledValidators = ();
 	type MaxAuthorities = MaxAuthorities;
-}
-
-parameter_types! {
-	pub const SessionPeriod: BlockNumber = HOURS;
-	pub const SessionOffset: BlockNumber = 0;
-}
-
-impl pallet_session::Config for Runtime {
-	type RuntimeEvent = RuntimeEvent;
-	type ValidatorId = <Self as frame_system::Config>::AccountId;
-	// we don't have stash and controller, thus we don't need the convert as well.
-	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
-	type ShouldEndSession = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
-	type NextSessionRotation = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
-	type SessionManager = CollatorSelection;
-	// Essentially just Aura, but lets be pedantic.
-	type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
-	type Keys = SessionKeys;
-	type WeightInfo = pallet_session::weights::SubstrateWeight<Self>; // ();
-}
-
-parameter_types! {
-	pub const UncleGenerations: u32 = 0;
-}
-
-impl pallet_authorship::Config for Runtime {
-	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
-	type UncleGenerations = UncleGenerations;
-	type FilterUncle = ();
-	type EventHandler = CollatorSelection;
-}
-
-parameter_types! {
-	pub const PotId: PalletId = PalletId(*b"PotStake");
-	pub const MaxCandidates: u32 = 1000;
-	pub const MinCandidates: u32 = 5;
-	pub const MaxInvulnerables: u32 = 100;
-}
-
-impl pallet_collator_selection::Config for Runtime {
-	type RuntimeEvent = RuntimeEvent;
-	type Currency = Balances;
-	// We allow root only to execute privileged collator selection operations.
-	type UpdateOrigin = EnsureRoot<AccountId>;
-	type PotId = PotId;
-	type MaxCandidates = MaxCandidates;
-	type MinCandidates = MinCandidates;
-	type MaxInvulnerables = MaxInvulnerables;
-	// Should be a multiple of session or things will get inconsistent.
-	type KickThreshold = SessionPeriod;
-	type ValidatorId = <Self as frame_system::Config>::AccountId;
-	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
-	type ValidatorRegistration = Session;
-	type WeightInfo = ();
 }
modifiedruntime/common/construct_runtime/mod.rsdiffbeforeafterboth
--- a/runtime/common/construct_runtime/mod.rs
+++ b/runtime/common/construct_runtime/mod.rs
@@ -32,9 +32,15 @@
                 ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
                 ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
 
+                #[runtimes(opal)]
                 Authorship: pallet_authorship::{Pallet, Call, Storage} = 22,
+
+                #[runtimes(opal)]
                 CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event<T>, Config<T>} = 23,
+
+                #[runtimes(opal)]
                 Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>} = 24,
+
                 Aura: pallet_aura::{Pallet, Config<T>} = 25,
                 AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 26,
 
modifiedruntime/common/mod.rsdiffbeforeafterboth
before · runtime/common/mod.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617pub mod config;18pub mod construct_runtime;19pub mod dispatch;20pub mod ethereum;21pub mod instance;22pub mod runtime_apis;2324#[cfg(feature = "scheduler")]25pub mod scheduler;2627pub mod sponsoring;28pub mod weights;2930#[cfg(test)]31pub mod tests;3233use sp_core::H160;34use frame_support::{35	traits::{Currency, OnUnbalanced, Imbalance},36	weights::Weight,37};38use sp_runtime::{39	generic,40	traits::{BlakeTwo256, BlockNumberProvider},41	impl_opaque_keys,42};43use sp_std::vec::Vec;4445#[cfg(feature = "std")]46use sp_version::NativeVersion;4748use crate::{49	Runtime, RuntimeCall, Balances, Treasury, Aura, Signature, AllPalletsWithSystem,50	InherentDataExt,51};52use up_common::types::{AccountId, BlockNumber};5354#[macro_export]55macro_rules! unsupported {56	() => {57		pallet_common::unsupported!($crate::Runtime)58	};59}6061/// The address format for describing accounts.62pub type Address = sp_runtime::MultiAddress<AccountId, ()>;63/// Block header type as expected by this runtime.64pub type Header = generic::Header<BlockNumber, BlakeTwo256>;65/// Block type as expected by this runtime.66pub type Block = generic::Block<Header, UncheckedExtrinsic>;67/// A Block signed with a Justification68pub type SignedBlock = generic::SignedBlock<Block>;69/// BlockId type as expected by this runtime.70pub type BlockId = generic::BlockId<Block>;7172impl_opaque_keys! {73	pub struct SessionKeys {74		pub aura: Aura,75	}76}7778/// The version information used to identify this runtime when compiled natively.79#[cfg(feature = "std")]80pub fn native_version() -> NativeVersion {81	NativeVersion {82		runtime_version: crate::VERSION,83		can_author_with: Default::default(),84	}85}8687pub type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;8889pub type SignedExtra = (90	frame_system::CheckSpecVersion<Runtime>,91	frame_system::CheckTxVersion<Runtime>,92	frame_system::CheckGenesis<Runtime>,93	frame_system::CheckEra<Runtime>,94	frame_system::CheckNonce<Runtime>,95	frame_system::CheckWeight<Runtime>,96	ChargeTransactionPayment,97	//pallet_contract_helpers::ContractHelpersExtension<Runtime>,98	pallet_ethereum::FakeTransactionFinalizer<Runtime>,99);100101/// Unchecked extrinsic type as expected by this runtime.102pub type UncheckedExtrinsic =103	fp_self_contained::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;104105/// Extrinsic type that has already been checked.106pub type CheckedExtrinsic =107	fp_self_contained::CheckedExtrinsic<AccountId, RuntimeCall, SignedExtra, H160>;108109/// Executive: handles dispatch to the various modules.110pub type Executive = frame_executive::Executive<111	Runtime,112	Block,113	frame_system::ChainContext<Runtime>,114	Runtime,115	AllPalletsWithSystem,116	AuraToCollatorSelection,117>;118119type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;120121pub struct DealWithFees;122impl OnUnbalanced<NegativeImbalance> for DealWithFees {123	fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {124		if let Some(fees) = fees_then_tips.next() {125			// for fees, 100% to treasury126			let mut split = fees.ration(100, 0);127			if let Some(tips) = fees_then_tips.next() {128				// for tips, if any, 100% to treasury129				tips.ration_merge_into(100, 0, &mut split);130			}131			Treasury::on_unbalanced(split.0);132			// Author::on_unbalanced(split.1);133		}134	}135}136137pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);138139impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider140	for RelayChainBlockNumberProvider<T>141{142	type BlockNumber = BlockNumber;143144	fn current_block_number() -> Self::BlockNumber {145		cumulus_pallet_parachain_system::Pallet::<T>::validation_data()146			.map(|d| d.relay_parent_number)147			.unwrap_or_default()148	}149}150151pub(crate) struct CheckInherents;152153impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {154	fn check_inherents(155		block: &Block,156		relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,157	) -> sp_inherents::CheckInherentsResult {158		let relay_chain_slot = relay_state_proof159			.read_slot()160			.expect("Could not read the relay chain slot from the proof");161162		let inherent_data =163			cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(164				relay_chain_slot,165				sp_std::time::Duration::from_secs(6),166			)167			.create_inherent_data()168			.expect("Could not create the timestamp inherent data");169170		inherent_data.check_extrinsics(block)171	}172}173174#[derive(codec::Encode, codec::Decode)]175pub enum XCMPMessage<XAccountId, XBalance> {176	/// Transfer tokens to the given account from the Parachain account.177	TransferToken(XAccountId, XBalance),178}179180pub struct AuraToCollatorSelection;181impl frame_support::traits::OnRuntimeUpgrade for AuraToCollatorSelection {182	fn on_runtime_upgrade() -> Weight {183		use frame_support::{BoundedVec, storage::migration};184		use sp_runtime::{185			traits::{OpaqueKeys, Saturating},186			RuntimeAppPublic,187		};188		use pallet_session::SessionManager;189		use up_common::constants::EXISTENTIAL_DEPOSIT;190		use crate::config::substrate::MaxInvulnerables;191192		let mut weight = <Runtime as frame_system::Config>::DbWeight::get().reads(1);193194		let version =195			migration::get_storage_value::<()>(b"AuraToCollatorSelection", b"StorageVersion", &[]);196197		let should_upgrade = match version {198			None => true,199			Some(_) => false,200		};201202		if should_upgrade {203			log::info!(204				target: "runtime::aura_to_collator_selection",205				"Running migration of Aura authorities to Collator Selection invulnerables"206			);207208			let invulnerables = pallet_aura::Pallet::<Runtime>::authorities()209				.iter()210				.cloned()211				.filter_map(|authority_id| {212					weight.saturating_accrue(<Runtime as frame_system::Config>::DbWeight::get().reads_writes(1, 1));213					let vec = authority_id.clone().to_raw_vec();214					let slice = vec.as_slice();215					let array: Option<[u8; 32]> = match slice.try_into() {216						Ok(a) => Some(a),217						Err(_) => {218							log::error!("Failed to convert an Aura authority to a Collator Selection invulnerable: {:?}", authority_id);219							None220						},221					};222					array.map(|a| (AccountId::from(a), authority_id))223				})224				.collect::<Vec<_>>();225226			let bounded_invulnerables = BoundedVec::<_, MaxInvulnerables>::try_from(227				invulnerables228					.iter()229					.cloned()230					.map(|(acc, _)| acc)231					.collect::<Vec<_>>(),232			)233			.expect("Existing collators/invulnerables are more than MaxInvulnerables");234235			<pallet_collator_selection::Invulnerables<Runtime>>::put(bounded_invulnerables);236			<pallet_collator_selection::DesiredCandidates<Runtime>>::put(0);237			<pallet_collator_selection::CandidacyBond<Runtime>>::put(EXISTENTIAL_DEPOSIT * 16);238239			let keys = invulnerables240				.into_iter()241				.map(|(acc, aura)| {242					(243						acc.clone(),                        // account id244						acc,                                // validator id245						SessionKeys { aura: aura.clone() }, // session keys246					)247				})248				.collect::<Vec<_>>();249250			for (account, val, keys) in keys.iter().cloned() {251				for id in <Runtime as pallet_session::Config>::Keys::key_ids() {252					<pallet_session::KeyOwner<Runtime>>::insert((*id, keys.get_raw(*id)), &val)253				}254				<pallet_session::NextKeys<Runtime>>::insert(&val, &keys);255				// todo exercise caution, the following is taken from genesis256				if frame_system::Pallet::<Runtime>::inc_consumers_without_limit(&account).is_err() {257					log::warn!(258						"We have entered an error with incrementing consumers without limit during the migration"259					);260					// This will leak a provider reference, however it only happens once (at261					// genesis) so it's really not a big deal and we assume that the user wants to262					// do this since it's the only way a non-endowed account can contain a session263					// key.264					frame_system::Pallet::<Runtime>::inc_providers(&account);265				}266			}267268			let initial_validators_0 =269				<Runtime as pallet_session::Config>::SessionManager::new_session(0).unwrap_or_else(270					|| {271						frame_support::print(272							"No initial validator provided by `SessionManager`, use \273						session config keys to generate initial validator set.",274						);275						keys.iter().map(|x| x.1.clone()).collect()276					},277				);278			/*assert!(279				!initial_validators_0.is_empty(),280				"Empty validator set for session 0 in (pseudo) genesis block!"281			);*/282283			let initial_validators_1 =284				<Runtime as pallet_session::Config>::SessionManager::new_session(1)285					.unwrap_or_else(|| initial_validators_0.clone());286			/*assert!(287				!initial_validators_1.is_empty(),288				"Empty validator set for session 1 in (pseudo) genesis block!"289			);*/290291			let queued_keys: Vec<_> = initial_validators_1292				.iter()293				.cloned()294				.map(|v| {295					(296						v.clone(),297						<pallet_session::NextKeys<Runtime>>::get(&v)298							.expect("Validator in session 1 missing keys!"),299					)300				})301				.collect();302303			// Tell everyone about the genesis session keys -- Aura must've already initialized it304			//<Runtime as pallet_session::Config>::SessionHandler::on_genesis_session::<<Runtime as pallet_session::Config>::Keys>(&queued_keys);305306			<pallet_session::Validators<Runtime>>::put(initial_validators_0);307			<pallet_session::QueuedKeys<Runtime>>::put(queued_keys);308309			<Runtime as pallet_session::Config>::SessionManager::start_session(0);310311			log::info!(312				target: "runtime::aura_to_collator_selection",313				"Migration of Aura authorities to Collator Selection invulnerables is complete."314			);315316			migration::put_storage_value::<()>(317				b"AuraToCollatorSelection",318				b"StorageVersion",319				&[],320				(),321			);322323			weight += <Runtime as frame_system::Config>::DbWeight::get().writes(1)324		} else {325			log::info!(326				target: "runtime::aura_to_collator_selection",327				"The storage migration has already been flagged as complete. No migration needs to be done.",328			);329		}330331		weight332	}333}
after · runtime/common/mod.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617pub mod config;18pub mod construct_runtime;19pub mod dispatch;20pub mod ethereum;21pub mod instance;22pub mod runtime_apis;2324#[cfg(feature = "scheduler")]25pub mod scheduler;2627pub mod sponsoring;28pub mod weights;2930#[cfg(test)]31pub mod tests;3233use sp_core::H160;34use frame_support::{35	traits::{Currency, OnUnbalanced, Imbalance},36	weights::Weight,37};38use sp_runtime::{39	generic,40	traits::{BlakeTwo256, BlockNumberProvider},41	impl_opaque_keys,42};43use sp_std::vec::Vec;4445#[cfg(feature = "std")]46use sp_version::NativeVersion;4748use crate::{49	Runtime, RuntimeCall, Balances, Treasury, Aura, Signature, AllPalletsWithSystem,50	InherentDataExt,51};52use up_common::types::{AccountId, BlockNumber};5354#[macro_export]55macro_rules! unsupported {56	() => {57		pallet_common::unsupported!($crate::Runtime)58	};59}6061/// The address format for describing accounts.62pub type Address = sp_runtime::MultiAddress<AccountId, ()>;63/// Block header type as expected by this runtime.64pub type Header = generic::Header<BlockNumber, BlakeTwo256>;65/// Block type as expected by this runtime.66pub type Block = generic::Block<Header, UncheckedExtrinsic>;67/// A Block signed with a Justification68pub type SignedBlock = generic::SignedBlock<Block>;69/// BlockId type as expected by this runtime.70pub type BlockId = generic::BlockId<Block>;7172impl_opaque_keys! {73	pub struct SessionKeys {74		pub aura: Aura,75	}76}7778/// The version information used to identify this runtime when compiled natively.79#[cfg(feature = "std")]80pub fn native_version() -> NativeVersion {81	NativeVersion {82		runtime_version: crate::VERSION,83		can_author_with: Default::default(),84	}85}8687pub type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;8889pub type SignedExtra = (90	frame_system::CheckSpecVersion<Runtime>,91	frame_system::CheckTxVersion<Runtime>,92	frame_system::CheckGenesis<Runtime>,93	frame_system::CheckEra<Runtime>,94	frame_system::CheckNonce<Runtime>,95	frame_system::CheckWeight<Runtime>,96	ChargeTransactionPayment,97	//pallet_contract_helpers::ContractHelpersExtension<Runtime>,98	pallet_ethereum::FakeTransactionFinalizer<Runtime>,99);100101/// Unchecked extrinsic type as expected by this runtime.102pub type UncheckedExtrinsic =103	fp_self_contained::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;104105/// Extrinsic type that has already been checked.106pub type CheckedExtrinsic =107	fp_self_contained::CheckedExtrinsic<AccountId, RuntimeCall, SignedExtra, H160>;108109/// Executive: handles dispatch to the various modules.110pub type Executive = frame_executive::Executive<111	Runtime,112	Block,113	frame_system::ChainContext<Runtime>,114	Runtime,115	AllPalletsWithSystem,116	AuraToCollatorSelection,117>;118119type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;120121pub struct DealWithFees;122impl OnUnbalanced<NegativeImbalance> for DealWithFees {123	fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {124		if let Some(fees) = fees_then_tips.next() {125			// for fees, 100% to treasury126			let mut split = fees.ration(100, 0);127			if let Some(tips) = fees_then_tips.next() {128				// for tips, if any, 100% to treasury129				tips.ration_merge_into(100, 0, &mut split);130			}131			Treasury::on_unbalanced(split.0);132			// Author::on_unbalanced(split.1);133		}134	}135}136137pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);138139impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider140	for RelayChainBlockNumberProvider<T>141{142	type BlockNumber = BlockNumber;143144	fn current_block_number() -> Self::BlockNumber {145		cumulus_pallet_parachain_system::Pallet::<T>::validation_data()146			.map(|d| d.relay_parent_number)147			.unwrap_or_default()148	}149}150151pub(crate) struct CheckInherents;152153impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {154	fn check_inherents(155		block: &Block,156		relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,157	) -> sp_inherents::CheckInherentsResult {158		let relay_chain_slot = relay_state_proof159			.read_slot()160			.expect("Could not read the relay chain slot from the proof");161162		let inherent_data =163			cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(164				relay_chain_slot,165				sp_std::time::Duration::from_secs(6),166			)167			.create_inherent_data()168			.expect("Could not create the timestamp inherent data");169170		inherent_data.check_extrinsics(block)171	}172}173174#[derive(codec::Encode, codec::Decode)]175pub enum XCMPMessage<XAccountId, XBalance> {176	/// Transfer tokens to the given account from the Parachain account.177	TransferToken(XAccountId, XBalance),178}179180pub struct AuraToCollatorSelection;181impl frame_support::traits::OnRuntimeUpgrade for AuraToCollatorSelection {182	fn on_runtime_upgrade() -> Weight {183		#[cfg(feature = "collator-selection")]184		{185			use frame_support::{BoundedVec, storage::migration};186			use sp_runtime::{187				traits::{OpaqueKeys, Saturating},188				RuntimeAppPublic,189			};190			use pallet_session::SessionManager;191			use up_common::constants::CANDIDACY_BOND;192			use crate::config::pallets::collator_selection::MaxInvulnerables;193194			let mut weight = <Runtime as frame_system::Config>::DbWeight::get().reads(1);195196			let version = migration::get_storage_value::<()>(197				b"AuraToCollatorSelection",198				b"StorageVersion",199				&[],200			);201202			let should_upgrade = match version {203				None => true,204				Some(_) => false,205			};206207			if should_upgrade {208				log::info!(209					target: "runtime::aura_to_collator_selection",210					"Running migration of Aura authorities to Collator Selection invulnerables"211				);212213				let invulnerables = pallet_aura::Pallet::<Runtime>::authorities()214					.iter()215					.cloned()216					.filter_map(|authority_id| {217						weight.saturating_accrue(<Runtime as frame_system::Config>::DbWeight::get().reads_writes(1, 1));218						let vec = authority_id.clone().to_raw_vec();219						let slice = vec.as_slice();220						let array: Option<[u8; 32]> = match slice.try_into() {221							Ok(a) => Some(a),222							Err(_) => {223								log::error!("Failed to convert an Aura authority to a Collator Selection invulnerable: {:?}", authority_id);224								None225							},226						};227						array.map(|a| (AccountId::from(a), authority_id))228					})229					.collect::<Vec<_>>();230231				let bounded_invulnerables = BoundedVec::<_, MaxInvulnerables>::try_from(232					invulnerables233						.iter()234						.cloned()235						.map(|(acc, _)| acc)236						.collect::<Vec<_>>(),237				)238				.expect("Existing collators/invulnerables are more than MaxInvulnerables");239240				<pallet_collator_selection::Invulnerables<Runtime>>::put(bounded_invulnerables);241				<pallet_collator_selection::DesiredCandidates<Runtime>>::put(0);242				<pallet_collator_selection::CandidacyBond<Runtime>>::put(CANDIDACY_BOND);243244				let keys = invulnerables245					.into_iter()246					.map(|(acc, aura)| {247						(248							acc.clone(),                        // account id249							acc,                                // validator id250							SessionKeys { aura: aura.clone() }, // session keys251						)252					})253					.collect::<Vec<_>>();254255				for (account, val, keys) in keys.iter().cloned() {256					for id in <Runtime as pallet_session::Config>::Keys::key_ids() {257						<pallet_session::KeyOwner<Runtime>>::insert((*id, keys.get_raw(*id)), &val)258					}259					<pallet_session::NextKeys<Runtime>>::insert(&val, &keys);260					// todo exercise caution, the following is taken from genesis261					if frame_system::Pallet::<Runtime>::inc_consumers_without_limit(&account)262						.is_err()263					{264						log::warn!(265							"We have entered an error with incrementing consumers without limit during the migration"266						);267						// This will leak a provider reference, however it only happens once (at268						// genesis) so it's really not a big deal and we assume that the user wants to269						// do this since it's the only way a non-endowed account can contain a session270						// key.271						frame_system::Pallet::<Runtime>::inc_providers(&account);272					}273				}274275				let initial_validators_0 =276					<Runtime as pallet_session::Config>::SessionManager::new_session(0)277						.unwrap_or_else(|| {278							frame_support::print(279								"No initial validator provided by `SessionManager`, use \280							session config keys to generate initial validator set.",281							);282							keys.iter().map(|x| x.1.clone()).collect()283						});284				/*assert!(285					!initial_validators_0.is_empty(),286					"Empty validator set for session 0 in (pseudo) genesis block!"287				);*/288289				let initial_validators_1 =290					<Runtime as pallet_session::Config>::SessionManager::new_session(1)291						.unwrap_or_else(|| initial_validators_0.clone());292				/*assert!(293					!initial_validators_1.is_empty(),294					"Empty validator set for session 1 in (pseudo) genesis block!"295				);*/296297				let queued_keys: Vec<_> = initial_validators_1298					.iter()299					.cloned()300					.map(|v| {301						(302							v.clone(),303							<pallet_session::NextKeys<Runtime>>::get(&v)304								.expect("Validator in session 1 missing keys!"),305						)306					})307					.collect();308309				// Tell everyone about the genesis session keys -- Aura must've already initialized it310				//<Runtime as pallet_session::Config>::SessionHandler::on_genesis_session::<<Runtime as pallet_session::Config>::Keys>(&queued_keys);311312				<pallet_session::Validators<Runtime>>::put(initial_validators_0);313				<pallet_session::QueuedKeys<Runtime>>::put(queued_keys);314315				<Runtime as pallet_session::Config>::SessionManager::start_session(0);316317				log::info!(318					target: "runtime::aura_to_collator_selection",319					"Migration of Aura authorities to Collator Selection invulnerables is complete."320				);321322				migration::put_storage_value::<()>(323					b"AuraToCollatorSelection",324					b"StorageVersion",325					&[],326					(),327				);328329				weight += <Runtime as frame_system::Config>::DbWeight::get().writes(1)330			} else {331				log::info!(332					target: "runtime::aura_to_collator_selection",333					"The storage migration has already been flagged as complete. No migration needs to be done.",334				);335			}336337			weight338		}339340		#[cfg(not(feature = "collator-selection"))]341		{342			Weight::zero()343		}344	}345}
modifiedruntime/opal/Cargo.tomldiffbeforeafterboth
--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -173,13 +173,14 @@
     "pallet-foreign-assets/std",
 ]
 limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
-opal-runtime = ['refungible', 'rmrk', 'app-promotion', 'foreign-assets']
+opal-runtime = ['refungible', 'rmrk', 'app-promotion', 'foreign-assets', 'collator-selection']
 
 refungible = []
 scheduler = []
 rmrk = []
 foreign-assets = []
 app-promotion = []
+collator-selection = []
 
 ################################################################################
 # Substrate Dependencies
modifiedruntime/quartz/Cargo.tomldiffbeforeafterboth
--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -177,6 +177,7 @@
 scheduler = []
 rmrk = []
 foreign-assets = []
+collator-selection = []
 
 ################################################################################
 # Substrate Dependencies
modifiedruntime/unique/Cargo.tomldiffbeforeafterboth
--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -178,6 +178,7 @@
 scheduler = []
 rmrk = []
 foreign-assets = []
+collator-selection = []
 
 ################################################################################
 # Substrate Dependencies