difftreelog
feat(collator-selection) opal only
in: master
10 files changed
node/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());
primitives/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>*/;
runtime/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 = ();
+}
runtime/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;
runtime/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 = ();
}
runtime/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,
runtime/common/mod.rsdiffbeforeafterboth1// 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}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}runtime/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
runtime/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
runtime/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