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

difftreelog

refactor! decouple pallet-collator-selection from pallet-configuration (#962)

Pavel Orlov2023-06-30parent: #1ecd8fc.patch.diff
in: master
* feat!: decoupling configuration&collators pallets

BREAKING CHANGE: pallet `collator-selection` no longer has a tight coupling with the `configuration` pallet

* refactor(collator-selection): type bounds, tests

* refactor(collator-selection): tests

* add ci step for banchmark tests

* add opsFee tests

---------

15 files changed

modified.github/workflows/yarn-dev.ymldiffbeforeafterboth
--- a/.github/workflows/yarn-dev.yml
+++ b/.github/workflows/yarn-dev.yml
@@ -87,6 +87,18 @@
         run: |
           echo "url is ${{ steps.test-report.outputs.runHtmlUrl }}"
 
+      - name: Run benchmark mintFee tests
+        working-directory: tests
+        run: |
+          yarn install
+          npx ts-node --esm ./src/benchmarks/mintFee/index.ts
+
+      - name: Run benchmark opsFee tests
+        working-directory: tests
+        run: |
+          yarn install
+          npx ts-node --esm ./src/benchmarks/opsFee/index.ts
+
       - name: Stop running containers
         if: always()                   # run this step always
         run: docker-compose -f ".docker/docker-compose.${{ matrix.network }}.yml" down
modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6371,7 +6371,7 @@
 
 [[package]]
 name = "pallet-collator-selection"
-version = "4.0.0"
+version = "5.0.0"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
@@ -6380,7 +6380,6 @@
  "pallet-aura",
  "pallet-authorship",
  "pallet-balances",
- "pallet-configuration",
  "pallet-session",
  "pallet-timestamp",
  "parity-scale-codec",
@@ -6435,7 +6434,7 @@
 
 [[package]]
 name = "pallet-configuration"
-version = "0.1.3"
+version = "0.2.0"
 dependencies = [
  "fp-evm",
  "frame-benchmarking",
modifiedpallets/collator-selection/CHANGELOG.mddiffbeforeafterboth
--- a/pallets/collator-selection/CHANGELOG.md
+++ b/pallets/collator-selection/CHANGELOG.md
@@ -4,22 +4,28 @@
 
 <!-- bureaucracy goes here -->
 
+## [5.0.0] - 2023-06-27
+
+### Major change
+
+- The dependency (tight coupling) this pallet on the configuration pallet has been removed.
+
 ## [4.0.0] - 2022-12-29
 
 ### Added
 
 - Entire functionality moved over from cumulus/pallet-collator-selection (v3.0.0). Refactored business logic:
-   - Added an extra step for candidacy, `get_license`, at which payment happens. The number of license holders is unlimited. 
-      - Only licensed accounts can apply for candidacy with `onboard`. No extra deposits are made.
-      - Active candidates may `offboard`, but they will retain their license.
-      - Deposit is returned, and candidacy possibly removed with `release_license`.
-      - License can be forcibly forfeited and candidacy removed with `force_release_license`.
-   - Failing collators' deposits will now be fully slashed, and funds will be redirected to Treasury.
-   - Unify `MaxInvulnerables` and `MaxCandidates` into `MaxCollators`.
-   - Remove `MinCandidates`.
-   - Minimal amount of invulnerables is now 1.
-   - Both invulnerables and candidates count against the limits together, however invulnerables ignore `DesiredCollators`.
-   - `KickThreshold` is made configurable.
-   - `DesiredCollators`, `LicenseBond`, and `KickThreshold` are moved to and referenced from `pallet-configuration`.
-   - Naming changes to better reflect the new functionality.
-   - More minor changes, tests, benchmarks, etc.
\ No newline at end of file
+  - Added an extra step for candidacy, `get_license`, at which payment happens. The number of license holders is unlimited.
+    - Only licensed accounts can apply for candidacy with `onboard`. No extra deposits are made.
+    - Active candidates may `offboard`, but they will retain their license.
+    - Deposit is returned, and candidacy possibly removed with `release_license`.
+    - License can be forcibly forfeited and candidacy removed with `force_release_license`.
+  - Failing collators' deposits will now be fully slashed, and funds will be redirected to Treasury.
+  - Unify `MaxInvulnerables` and `MaxCandidates` into `MaxCollators`.
+  - Remove `MinCandidates`.
+  - Minimal amount of invulnerables is now 1.
+  - Both invulnerables and candidates count against the limits together, however invulnerables ignore `DesiredCollators`.
+  - `KickThreshold` is made configurable.
+  - `DesiredCollators`, `LicenseBond`, and `KickThreshold` are moved to and referenced from `pallet-configuration`.
+  - Naming changes to better reflect the new functionality.
+  - More minor changes, tests, benchmarks, etc.
modifiedpallets/collator-selection/Cargo.tomldiffbeforeafterboth
--- a/pallets/collator-selection/Cargo.toml
+++ b/pallets/collator-selection/Cargo.toml
@@ -6,7 +6,7 @@
 license = "GPLv3"
 name = "pallet-collator-selection"
 repository = "https://github.com/UniqueNetwork/unique-chain"
-version = "4.0.0"
+version = "5.0.0"
 
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
@@ -23,7 +23,6 @@
 frame-support = { workspace = true }
 frame-system = { workspace = true }
 pallet-authorship = { workspace = true }
-pallet-configuration = { workspace = true }
 pallet-session = { workspace = true }
 sp-runtime = { workspace = true }
 sp-staking = { workspace = true }
@@ -55,8 +54,6 @@
 	"frame-system/std",
 	"log/std",
 	"pallet-authorship/std",
-	'pallet-aura/std',
-	'pallet-balances/std',
 	"pallet-session/std",
 	"rand/std",
 	"scale-info/std",
@@ -64,6 +61,8 @@
 	"sp-runtime/std",
 	"sp-staking/std",
 	"sp-std/std",
+	'pallet-aura/std',
+	'pallet-balances/std',
 ]
 
 try-runtime = ["frame-support/try-runtime"]
modifiedpallets/collator-selection/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/collator-selection/src/benchmarking.rs
+++ b/pallets/collator-selection/src/benchmarking.rs
@@ -35,7 +35,7 @@
 use super::*;
 
 #[allow(unused)]
-use crate::Pallet as CollatorSelection;
+use crate::{Pallet as CollatorSelection, BalanceOf};
 use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller};
 use frame_support::{
 	assert_ok,
@@ -49,11 +49,6 @@
 use frame_system::{EventRecord, RawOrigin};
 use pallet_authorship::EventHandler;
 use pallet_session::{self as session, SessionManager};
-use pallet_configuration::{
-	self as configuration, BalanceOf,
-	CollatorSelectionDesiredCollatorsOverride as DesiredCollators,
-	CollatorSelectionLicenseBondOverride as LicenseBond,
-};
 use sp_std::prelude::*;
 
 const SEED: u32 = 0;
@@ -117,7 +112,7 @@
 	validators.into_iter().map(|(who, _)| who).collect()
 }
 
-fn register_invulnerables<T: Config + configuration::Config>(count: u32) {
+fn register_invulnerables<T: Config>(count: u32) {
 	let candidates = (0..count)
 		.map(|c| account("candidate", c, SEED))
 		.collect::<Vec<_>>();
@@ -131,33 +126,27 @@
 	}
 }
 
-fn register_candidates<T: Config + configuration::Config>(count: u32) {
+fn register_candidates<T: Config>(count: u32) {
 	let candidates = (0..count)
 		.map(|c| account("candidate", c, SEED))
 		.collect::<Vec<_>>();
-	assert!(
-		<LicenseBond<T>>::get() > 0u32.into(),
-		"Bond cannot be zero!"
-	);
+	assert!(T::LicenseBond::get() > 0u32.into(), "Bond cannot be zero!");
 
 	for who in candidates {
-		T::Currency::set_balance(&who, <LicenseBond<T>>::get() * 2u32.into());
+		T::Currency::set_balance(&who, T::LicenseBond::get() * 2u32.into());
 		<CollatorSelection<T>>::get_license(RawOrigin::Signed(who.clone()).into()).unwrap();
 		<CollatorSelection<T>>::onboard(RawOrigin::Signed(who).into()).unwrap();
 	}
 }
 
-fn get_licenses<T: Config + configuration::Config>(count: u32) {
+fn get_licenses<T: Config>(count: u32) {
 	let candidates = (0..count)
 		.map(|c| account("candidate", c, SEED))
 		.collect::<Vec<_>>();
-	assert!(
-		<LicenseBond<T>>::get() > 0u32.into(),
-		"Bond cannot be zero!"
-	);
+	assert!(T::LicenseBond::get() > 0u32.into(), "Bond cannot be zero!");
 
 	for who in candidates {
-		T::Currency::set_balance(&who, <LicenseBond<T>>::get() * 2u32.into());
+		T::Currency::set_balance(&who, T::LicenseBond::get() * 2u32.into());
 		<CollatorSelection<T>>::get_license(RawOrigin::Signed(who.clone()).into()).unwrap();
 	}
 }
@@ -165,7 +154,7 @@
 /// `Currency::minimum_balance` was used originally, but in unique-chain, we have
 /// zero existential deposit, thus triggering zero bond assertion.
 fn balance_unit<T: Config>() -> BalanceOf<T> {
-	200u32.into()
+	T::LicenseBond::get()
 }
 
 /// Our benchmarking environment already has invulnerables registered.
@@ -173,7 +162,7 @@
 
 benchmarks! {
 	where_clause { where
-		T: pallet_authorship::Config + session::Config + configuration::Config
+		T: Config + pallet_authorship::Config + session::Config
 	}
 
 	// todo:collator this and all the following do not work for some reason, going all the way up to 10 in length
@@ -188,7 +177,7 @@
 
 		let new_invulnerable: T::AccountId = whitelisted_caller();
 		let bond: BalanceOf<T> = balance_unit::<T>() * 2u32.into();
-		T::Currency::set_balance(&new_invulnerable, bond.clone());
+		<T as Config>::Currency::set_balance(&new_invulnerable, bond);
 
 		<session::Pallet<T>>::set_keys(
 			RawOrigin::Signed(new_invulnerable.clone()).into(),
@@ -225,15 +214,13 @@
 
 	get_license {
 		let c in 1 .. T::MaxCollators::get() - 1;
-
-		<LicenseBond<T>>::put(balance_unit::<T>());
 
 		register_validators::<T>(c);
 		get_licenses::<T>(c);
 
 		let caller: T::AccountId = whitelisted_caller();
 		let bond: BalanceOf<T> = balance_unit::<T>() * 2u32.into();
-		T::Currency::set_balance(&caller, bond.clone());
+		T::Currency::set_balance(&caller, bond);
 
 		<session::Pallet<T>>::set_keys(
 			RawOrigin::Signed(caller.clone()).into(),
@@ -251,15 +238,12 @@
 	onboard {
 		let c in 1 .. T::MaxCollators::get() - INITIAL_INVULNERABLES - 1;
 
-		<LicenseBond<T>>::put(balance_unit::<T>());
-		<DesiredCollators<T>>::put(c + INITIAL_INVULNERABLES + 1);
-
 		register_validators::<T>(c);
 		register_candidates::<T>(c);
 
 		let caller: T::AccountId = whitelisted_caller();
 		let bond: BalanceOf<T> = balance_unit::<T>() * 2u32.into();
-		T::Currency::set_balance(&caller, bond.clone());
+		T::Currency::set_balance(&caller, bond);
 
 		let origin = RawOrigin::Signed(caller.clone());
 
@@ -279,9 +263,7 @@
 
 	// worst case is the last candidate leaving.
 	offboard {
-		let c in 1 .. T::MaxCollators::get();
-		<LicenseBond<T>>::put(balance_unit::<T>());
-		<DesiredCollators<T>>::put(c + INITIAL_INVULNERABLES);
+		let c in 1 .. T::MaxCollators::get() - INITIAL_INVULNERABLES;
 
 		register_validators::<T>(c);
 		register_candidates::<T>(c);
@@ -295,10 +277,8 @@
 
 	// worst case is the last candidate leaving.
 	release_license {
-		let c in 1 .. T::MaxCollators::get();
+		let c in 1 .. T::MaxCollators::get() - INITIAL_INVULNERABLES;
 		let bond = balance_unit::<T>();
-		<LicenseBond<T>>::put(bond);
-		<DesiredCollators<T>>::put(c + INITIAL_INVULNERABLES);
 
 		register_validators::<T>(c);
 		register_candidates::<T>(c);
@@ -312,10 +292,8 @@
 
 	// worst case is the last candidate leaving.
 	force_release_license {
-		let c in 1 .. T::MaxCollators::get();
+		let c in 1 .. T::MaxCollators::get() - INITIAL_INVULNERABLES;
 		let bond = balance_unit::<T>();
-		<LicenseBond<T>>::put(bond);
-		<DesiredCollators<T>>::put(c + INITIAL_INVULNERABLES);
 
 		register_validators::<T>(c);
 		register_candidates::<T>(c);
@@ -334,7 +312,6 @@
 
 	// worst case is paying a non-existing candidate account.
 	note_author {
-		<LicenseBond<T>>::put(balance_unit::<T>());
 		T::Currency::set_balance(
 			&<CollatorSelection<T>>::account_id(),
 			balance_unit::<T>() * 4u32.into(),
@@ -353,11 +330,9 @@
 
 	// worst case for new session.
 	new_session {
-		let r in 1 .. T::MaxCollators::get();
-		let c in 1 .. T::MaxCollators::get();
+		let r in 1 .. T::MaxCollators::get() - INITIAL_INVULNERABLES;
+		let c in 1 .. T::MaxCollators::get() - INITIAL_INVULNERABLES;
 
-		<LicenseBond<T>>::put(balance_unit::<T>());
-		<DesiredCollators<T>>::put(c + INITIAL_INVULNERABLES);
 		frame_system::Pallet::<T>::set_block_number(0u32.into());
 
 		register_validators::<T>(c);
modifiedpallets/collator-selection/src/lib.rsdiffbeforeafterboth
after · pallets/collator-selection/src/lib.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/>.1617// Original license:18// Copyright (C) 2021 Parity Technologies (UK) Ltd.19// SPDX-License-Identifier: Apache-2.02021// Licensed under the Apache License, Version 2.0 (the "License");22// you may not use this file except in compliance with the License.23// You may obtain a copy of the License at24//25// 	http://www.apache.org/licenses/LICENSE-2.026//27// Unless required by applicable law or agreed to in writing, software28// distributed under the License is distributed on an "AS IS" BASIS,29// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.30// See the License for the specific language governing permissions and31// limitations under the License.3233// todo:collator documentation34//! Collator Selection pallet.35//!36//! A pallet to manage collators in a parachain.37//!38//! ## Overview39//!40//! The Collator Selection pallet manages the collators of a parachain. **Collation is _not_ a41//! secure activity** and this pallet does not implement any game-theoretic mechanisms to meet BFT42//! safety assumptions of the chosen set.43//!44//! ## Terminology45//!46//! - Collator: A parachain block producer.47//! - Bond: An amount of `Balance` _reserved_ for candidate registration.48//! - Invulnerable: An account guaranteed to be in the collator set.49//!50//! ## Implementation51//!52//! The final `Collators` are aggregated from two individual lists:53//!54//! 1. [`Invulnerables`]: a set of collators appointed by governance. These accounts will always be55//!    collators.56//! 2. [`Candidates`]: these are *candidates to the collation task* and may or may not be elected as57//!    a final collator.58//!59//! The current implementation resolves congestion of [`Candidates`] in a first-come-first-serve60//! manner.61//!62//! Candidates will not be allowed to get kicked or leave_intent if the total number of candidates63//! fall below MinCandidates. This is for potential disaster recovery scenarios.64//!65//! ### Rewards66//!67//! The Collator Selection pallet maintains an on-chain account (the "Pot"). In each block, the68//! collator who authored it receives:69//!70//! - Half the value of the Pot.71//! - Half the value of the transaction fees within the block. The other half of the transaction72//!   fees are deposited into the Pot.73//!74//! To initiate rewards an ED needs to be transferred to the pot address.75//!76//! Note: Eventually the Pot distribution may be modified as discussed in77//! [this issue](https://github.com/paritytech/statemint/issues/21#issuecomment-810481073).7879#![cfg_attr(not(feature = "std"), no_std)]8081pub use pallet::*;8283#[cfg(test)]84mod mock;8586#[cfg(test)]87mod tests;8889#[cfg(feature = "runtime-benchmarks")]90mod benchmarking;91pub mod weights;9293use frame_support::traits::fungible::Inspect;9495type BalanceOf<T> =96	<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;97#[frame_support::pallet]98pub mod pallet {99	use super::*;100	pub use crate::weights::WeightInfo;101	use core::ops::Div;102	use frame_support::{103		dispatch::{DispatchClass, DispatchResultWithPostInfo},104		inherent::Vec,105		pallet_prelude::*,106		sp_runtime::traits::{AccountIdConversion, CheckedSub, Saturating, Zero},107		traits::{108			EnsureOrigin,109			fungible::{Balanced, BalancedHold, Inspect, InspectHold, Mutate, MutateHold},110			ValidatorRegistration,111			tokens::{Precision, Preservation},112		},113		BoundedVec, PalletId,114	};115	use frame_system::pallet_prelude::*;116	use pallet_session::SessionManager;117	use sp_runtime::{Perbill, traits::Convert};118	use sp_staking::SessionIndex;119120	/// A convertor from collators id. Since this pallet does not have stash/controller, this is121	/// just identity.122	pub struct IdentityCollator;123	impl<T> sp_runtime::traits::Convert<T, Option<T>> for IdentityCollator {124		fn convert(t: T) -> Option<T> {125			Some(t)126		}127	}128129	/// Configure the pallet by specifying the parameters and types on which it depends.130	#[pallet::config]131	pub trait Config: frame_system::Config {132		/// Overarching event type.133		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;134		type Currency: Mutate<Self::AccountId>135			+ MutateHold<Self::AccountId>136			+ BalancedHold<Self::AccountId>;137138		/// Origin that can dictate updating parameters of this pallet.139		type UpdateOrigin: EnsureOrigin<Self::RuntimeOrigin>;140141		/// Account Identifier that holds the chain's treasury.142		type TreasuryAccountId: Get<Self::AccountId>;143144		/// Account Identifier from which the internal Pot is generated.145		type PotId: Get<PalletId>;146147		/// Maximum number of candidates and invulnerables that we should have. This is enforced in code.148		type MaxCollators: Get<u32>;149150		/// If kicked, how much of the collator's deposit will be slashed and sent to the slash destination.151		type SlashRatio: Get<Perbill>;152153		/// A stable ID for a validator.154		type ValidatorId: Member + Parameter;155156		/// A conversion from account ID to validator ID.157		///158		/// Its cost must be at most one storage read.159		type ValidatorIdOf: Convert<Self::AccountId, Option<Self::ValidatorId>>;160161		/// Validate a user is registered162		type ValidatorRegistration: ValidatorRegistration<Self::ValidatorId>;163164		/// The weight information of this pallet.165		type WeightInfo: WeightInfo;166167		#[pallet::constant]168		type LicenceBondIdentifier: Get<<Self::Currency as InspectHold<Self::AccountId>>::Reason>;169170		type DesiredCollators: Get<u32>;171172		type LicenseBond: Get<BalanceOf<Self>>;173174		type KickThreshold: Get<Self::BlockNumber>;175	}176177	#[pallet::pallet]178	pub struct Pallet<T>(_);179180	/// The invulnerable, fixed collators.181	#[pallet::storage]182	#[pallet::getter(fn invulnerables)]183	pub type Invulnerables<T: Config> =184		StorageValue<_, BoundedVec<T::AccountId, T::MaxCollators>, ValueQuery>;185186	/// The (community) collation license holders.187	#[pallet::storage]188	#[pallet::getter(fn license_deposit_of)]189	pub type LicenseDepositOf<T: Config> =190		StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf<T>, ValueQuery>;191192	/// The (community, limited) collation candidates.193	#[pallet::storage]194	#[pallet::getter(fn candidates)]195	pub type Candidates<T: Config> =196		StorageValue<_, BoundedVec<T::AccountId, T::MaxCollators>, ValueQuery>;197198	/// Last block authored by collator.199	#[pallet::storage]200	#[pallet::getter(fn last_authored_block)]201	pub type LastAuthoredBlock<T: Config> =202		StorageMap<_, Twox64Concat, T::AccountId, T::BlockNumber, ValueQuery>;203204	#[pallet::genesis_config]205	pub struct GenesisConfig<T: Config> {206		pub invulnerables: Vec<T::AccountId>,207	}208209	#[cfg(feature = "std")]210	impl<T: Config> Default for GenesisConfig<T> {211		fn default() -> Self {212			Self {213				invulnerables: Default::default(),214			}215		}216	}217218	#[pallet::genesis_build]219	impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {220		fn build(&self) {221			let duplicate_invulnerables = self222				.invulnerables223				.iter()224				.collect::<std::collections::BTreeSet<_>>();225			assert!(226				duplicate_invulnerables.len() == self.invulnerables.len(),227				"duplicate invulnerables in genesis."228			);229230			let bounded_invulnerables =231				BoundedVec::<_, T::MaxCollators>::try_from(self.invulnerables.clone())232					.expect("genesis invulnerables are more than T::MaxCollators");233234			<Invulnerables<T>>::put(bounded_invulnerables);235		}236	}237238	#[pallet::event]239	#[pallet::generate_deposit(pub(super) fn deposit_event)]240	pub enum Event<T: Config> {241		InvulnerableAdded {242			invulnerable: T::AccountId,243		},244		InvulnerableRemoved {245			invulnerable: T::AccountId,246		},247		LicenseObtained {248			account_id: T::AccountId,249			deposit: BalanceOf<T>,250		},251		LicenseReleased {252			account_id: T::AccountId,253			deposit_returned: BalanceOf<T>,254		},255		CandidateAdded {256			account_id: T::AccountId,257		},258		CandidateRemoved {259			account_id: T::AccountId,260		},261	}262263	// Errors inform users that something went wrong.264	#[pallet::error]265	pub enum Error<T> {266		/// Too many candidates267		TooManyCandidates,268		/// Unknown error269		Unknown,270		/// Permission issue271		Permission,272		/// User already holds license to collate273		AlreadyHoldingLicense,274		/// User does not hold a license to collate275		NoLicense,276		/// User is already a candidate277		AlreadyCandidate,278		/// User is not a candidate279		NotCandidate,280		/// Too many invulnerables281		TooManyInvulnerables,282		/// Too few invulnerables283		TooFewInvulnerables,284		/// User is already an Invulnerable285		AlreadyInvulnerable,286		/// User is not an Invulnerable287		NotInvulnerable,288		/// Account has no associated validator ID289		NoAssociatedValidatorId,290		/// Validator ID is not yet registered291		ValidatorNotRegistered,292	}293294	#[pallet::hooks]295	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}296297	#[pallet::call]298	impl<T: Config> Pallet<T> {299		/// Add a collator to the list of invulnerable (fixed) collators.300		#[pallet::call_index(0)]301		#[pallet::weight(<T as Config>::WeightInfo::add_invulnerable(T::MaxCollators::get()))]302		pub fn add_invulnerable(303			origin: OriginFor<T>,304			new: T::AccountId,305		) -> DispatchResultWithPostInfo {306			T::UpdateOrigin::ensure_origin(origin)?;307308			// check if the new invulnerable has associated validator keys before it is added309			let validator_key = T::ValidatorIdOf::convert(new.clone())310				.ok_or(Error::<T>::NoAssociatedValidatorId)?;311			ensure!(312				T::ValidatorRegistration::is_registered(&validator_key),313				Error::<T>::ValidatorNotRegistered314			);315			if Self::invulnerables().contains(&new) {316				return Ok(().into());317			}318319			<Invulnerables<T>>::try_append(new.clone())320				.map_err(|_| Error::<T>::TooManyInvulnerables)?;321322			// try to offboard the new invulnerable if it was a collator candidate before323			let _ = Self::try_remove_candidate(&new);324325			Self::deposit_event(Event::InvulnerableAdded { invulnerable: new });326			Ok(().into())327		}328329		/// Remove a collator from the list of invulnerable (fixed) collators.330		#[pallet::call_index(1)]331		#[pallet::weight(<T as Config>::WeightInfo::remove_invulnerable(T::MaxCollators::get()))]332		pub fn remove_invulnerable(333			origin: OriginFor<T>,334			who: T::AccountId,335		) -> DispatchResultWithPostInfo {336			T::UpdateOrigin::ensure_origin(origin)?;337338			<Invulnerables<T>>::try_mutate(|invulnerables| -> DispatchResult {339				if invulnerables.len() <= 1 {340					return Err(Error::<T>::TooFewInvulnerables.into());341				}342343				let index = invulnerables344					.into_iter()345					.position(|r| *r == who)346					.ok_or(Error::<T>::NotInvulnerable)?;347				invulnerables.remove(index);348				Ok(())349			})?;350			Self::deposit_event(Event::InvulnerableRemoved { invulnerable: who });351			Ok(().into())352		}353354		/// Purchase a license on block collation for this account.355		/// It does not make it a collator candidate, use `onboard` afterward. The account must356		/// (a) already have registered session keys and (b) be able to reserve the `LicenseBond`.357		///358		/// This call is not available to `Invulnerable` collators.359		#[pallet::call_index(2)]360		#[pallet::weight(<T as Config>::WeightInfo::get_license(T::MaxCollators::get()))]361		pub fn get_license(origin: OriginFor<T>) -> DispatchResultWithPostInfo {362			// register_as_candidate363			let who = ensure_signed(origin)?;364365			if LicenseDepositOf::<T>::contains_key(&who) {366				return Err(Error::<T>::AlreadyHoldingLicense.into());367			}368369			let validator_key = T::ValidatorIdOf::convert(who.clone())370				.ok_or(Error::<T>::NoAssociatedValidatorId)?;371			ensure!(372				T::ValidatorRegistration::is_registered(&validator_key),373				Error::<T>::ValidatorNotRegistered374			);375376			let deposit = T::LicenseBond::get();377378			T::Currency::hold(&T::LicenceBondIdentifier::get(), &who, deposit)?;379			LicenseDepositOf::<T>::insert(who.clone(), deposit);380381			Self::deposit_event(Event::LicenseObtained {382				account_id: who,383				deposit,384			});385			Ok(().into()) // Some(T::WeightInfo::register_as_candidate(current_count as u32)).into())386		}387388		/// Register this account as a candidate for collators for next sessions.389		/// The account must already hold a license, and cannot offboard immediately during a session.390		///391		/// This call is not available to `Invulnerable` collators.392		#[pallet::call_index(3)]393		#[pallet::weight(<T as Config>::WeightInfo::onboard(T::MaxCollators::get()))]394		pub fn onboard(origin: OriginFor<T>) -> DispatchResultWithPostInfo {395			// register_as_candidate396			let who = ensure_signed(origin)?;397398			// ensure the user obtained the license.399			ensure!(400				LicenseDepositOf::<T>::contains_key(&who),401				Error::<T>::NoLicense402			);403			// ensure we are below limit.404			let length = <Candidates<T>>::decode_len().unwrap_or_default()405				+ <Invulnerables<T>>::decode_len().unwrap_or_default();406			ensure!(407				(length as u32) < T::DesiredCollators::get(),408				Error::<T>::TooManyCandidates409			);410			ensure!(411				!Self::invulnerables().contains(&who),412				Error::<T>::AlreadyInvulnerable413			);414415			let current_count =416				<Candidates<T>>::try_mutate(|candidates| -> Result<usize, DispatchError> {417					if candidates.iter().any(|candidate| *candidate == who) {418						Err(Error::<T>::AlreadyCandidate)?419					} else {420						candidates421							.try_push(who.clone())422							.map_err(|_| Error::<T>::TooManyCandidates)?;423						// First authored block is current block plus kick threshold to handle session delay424						<LastAuthoredBlock<T>>::insert(425							who.clone(),426							frame_system::Pallet::<T>::block_number() + T::KickThreshold::get(),427						);428						Ok(candidates.len())429					}430				})?;431432			Self::deposit_event(Event::CandidateAdded { account_id: who });433			Ok(Some(<T as Config>::WeightInfo::onboard(current_count as u32)).into())434		}435436		/// Deregister `origin` as a collator candidate. Note that the collator can only leave on437		/// session change. The license to `onboard` later at any other time will remain.438		#[pallet::call_index(4)]439		#[pallet::weight(<T as Config>::WeightInfo::offboard(T::MaxCollators::get()))]440		pub fn offboard(origin: OriginFor<T>) -> DispatchResultWithPostInfo {441			// leave_intent442			let who = ensure_signed(origin)?;443			let current_count = Self::try_remove_candidate(&who)?;444445			Ok(Some(<T as Config>::WeightInfo::offboard(current_count as u32)).into())446		}447448		/// Forfeit `origin`'s own license. The `LicenseBond` will be unreserved immediately.449		///450		/// This call is not available to `Invulnerable` collators.451		#[pallet::call_index(5)]452		#[pallet::weight(<T as Config>::WeightInfo::release_license(T::MaxCollators::get()))]453		pub fn release_license(origin: OriginFor<T>) -> DispatchResultWithPostInfo {454			// leave_intent455			let who = ensure_signed(origin)?;456457			let current_count = Self::try_remove_candidate_and_release_license(&who, false, true)?;458459			Ok(Some(<T as Config>::WeightInfo::release_license(460				current_count as u32,461			))462			.into())463		}464465		/// Force deregister `origin` as a collator candidate as a governing authority, and revoke its license.466		/// Note that the collator can only leave on session change.467		/// The `LicenseBond` will be unreserved and returned immediately.468		///469		/// This call is, of course, not applicable to `Invulnerable` collators.470		#[pallet::call_index(6)]471		#[pallet::weight(<T as Config>::WeightInfo::force_release_license(T::MaxCollators::get()))]472		pub fn force_release_license(473			origin: OriginFor<T>,474			who: T::AccountId,475		) -> DispatchResultWithPostInfo {476			// leave_intent477			T::UpdateOrigin::ensure_origin(origin)?;478479			let current_count = Self::try_remove_candidate_and_release_license(&who, false, true)?;480481			Ok(Some(<T as Config>::WeightInfo::force_release_license(482				current_count as u32,483			))484			.into())485		}486	}487488	impl<T: Config> Pallet<T> {489		/// Get a unique, inaccessible account id from the `PotId`.490		pub fn account_id() -> T::AccountId {491			T::PotId::get().into_account_truncating()492		}493494		/// Removes a candidate and their license, optionally slashed and optionally ignoring,495		/// whether or not they actually are a candidate.496		fn try_remove_candidate_and_release_license(497			who: &T::AccountId,498			should_slash: bool,499			ignore_if_not_candidate: bool,500		) -> Result<usize, DispatchError> {501			let current_count = Self::try_remove_candidate(who);502			let current_count = if ignore_if_not_candidate503				&& current_count == Err(Error::<T>::NotCandidate.into())504			{505				<Candidates<T>>::decode_len().unwrap_or_default()506			} else {507				current_count?508			};509			Self::try_release_license(who, should_slash)?;510			Ok(current_count)511		}512513		/// Removes a candidate from the collator pool for the next session if they exist.514		fn try_remove_candidate(who: &T::AccountId) -> Result<usize, DispatchError> {515			let current_count =516				<Candidates<T>>::try_mutate(|candidates| -> Result<usize, DispatchError> {517					let index = candidates518						.iter()519						.position(|candidate| *candidate == *who)520						.ok_or(Error::<T>::NotCandidate)?;521					candidates.remove(index);522					<LastAuthoredBlock<T>>::remove(who.clone());523					Ok(candidates.len())524				})?;525			Self::deposit_event(Event::CandidateRemoved {526				account_id: who.clone(),527			});528			Ok(current_count)529		}530531		/// Removes a candidate if they exist and sends them back their deposit, optionally slashed.532		fn try_release_license(who: &T::AccountId, should_slash: bool) -> DispatchResult {533			let mut deposit_returned = BalanceOf::<T>::default();534			LicenseDepositOf::<T>::try_mutate_exists(who, |deposit| -> DispatchResult {535				if let Some(deposit) = deposit.take() {536					if should_slash {537						let slashed = T::SlashRatio::get() * deposit;538						let remaining = deposit - slashed;539540						let (imbalance, _) =541							T::Currency::slash(&T::LicenceBondIdentifier::get(), who, slashed);542						deposit_returned = remaining;543544						T::Currency::resolve(&T::TreasuryAccountId::get(), imbalance)545							.map_err(|_| DispatchError::Other("Failed to deposit imbalance"))?;546					} else {547						deposit_returned = deposit;548					}549550					T::Currency::release(551						&T::LicenceBondIdentifier::get(),552						who,553						deposit_returned,554						Precision::Exact,555					)?;556					Ok(())557				} else {558					Err(Error::<T>::NoLicense.into())559				}560			})?;561			Self::deposit_event(Event::LicenseReleased {562				account_id: who.clone(),563				deposit_returned,564			});565			Ok(())566		}567568		/// Assemble the current set of candidates and invulnerables into the next collator set.569		///570		/// This is done on the fly, as frequent as we are told to do so, as the session manager.571		pub fn assemble_collators(572			candidates: BoundedVec<T::AccountId, T::MaxCollators>,573		) -> Vec<T::AccountId> {574			let mut collators = Self::invulnerables().to_vec();575			collators.extend(candidates);576			collators577		}578579		/// Kicks out candidates that did not produce a block in the kick threshold580		/// and **confiscates** their deposits to the treasury.581		pub fn kick_stale_candidates(582			candidates: BoundedVec<T::AccountId, T::MaxCollators>,583		) -> BoundedVec<T::AccountId, T::MaxCollators> {584			let now = frame_system::Pallet::<T>::block_number();585			let kick_threshold = T::KickThreshold::get();586			candidates587				.into_iter()588				.filter_map(|c| {589					let last_block = <LastAuthoredBlock<T>>::get(c.clone());590					let since_last = now.saturating_sub(last_block);591					if since_last < kick_threshold {592						Some(c)593					} else {594						let outcome = Self::try_remove_candidate_and_release_license(&c, true, false);595						if let Err(why) = outcome {596							log::warn!("Failed to kick collator and release license {:?}", why);597							debug_assert!(false, "failed to kick collator and release license {why:?}");598						}599						None600					}601				})602				.collect::<Vec<_>>()603				.try_into()604				.expect("filter_map operation can't result in a bounded vec larger than its original; qed")605		}606	}607608	/// Keep track of number of authored blocks per authority, uncles are counted as well since609	/// they're a valid proof of being online.610	impl<T: Config + pallet_authorship::Config>611		pallet_authorship::EventHandler<T::AccountId, T::BlockNumber> for Pallet<T>612	{613		fn note_author(author: T::AccountId) {614			let pot = Self::account_id();615			// assumes an ED will be sent to pot.616			let reward = T::Currency::balance(&pot)617				.checked_sub(&T::Currency::minimum_balance())618				.unwrap_or_else(Zero::zero)619				.div(2u32.into());620621			if !reward.is_zero() {622				// `reward` is half of pot account minus ED, this should never fail.623				let _success = T::Currency::transfer(&pot, &author, reward, Preservation::Preserve);624				debug_assert!(_success.is_ok());625			}626			<LastAuthoredBlock<T>>::insert(author, frame_system::Pallet::<T>::block_number());627628			frame_system::Pallet::<T>::register_extra_weight_unchecked(629				<T as Config>::WeightInfo::note_author(),630				DispatchClass::Mandatory,631			);632		}633	}634635	/// Play the role of the session manager.636	impl<T: Config> SessionManager<T::AccountId> for Pallet<T> {637		fn new_session(index: SessionIndex) -> Option<Vec<T::AccountId>> {638			log::info!(639				"assembling new collators for new session {} at #{:?}",640				index,641				<frame_system::Pallet<T>>::block_number(),642			);643644			let candidates = Self::candidates();645			let candidates_len_before = candidates.len();646			let active_candidates = Self::kick_stale_candidates(candidates);647			let removed = candidates_len_before - active_candidates.len();648			let result = Self::assemble_collators(active_candidates);649650			frame_system::Pallet::<T>::register_extra_weight_unchecked(651				<T as Config>::WeightInfo::new_session(652					candidates_len_before as u32,653					removed as u32,654				),655				DispatchClass::Mandatory,656			);657			Some(result)658		}659		fn start_session(_: SessionIndex) {660			// we don't care.661		}662		fn end_session(_: SessionIndex) {663			// we don't care.664		}665	}666}
modifiedpallets/collator-selection/src/mock.rsdiffbeforeafterboth
--- a/pallets/collator-selection/src/mock.rs
+++ b/pallets/collator-selection/src/mock.rs
@@ -63,7 +63,6 @@
 		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
 		CollatorSelection: collator_selection::{Pallet, Call, Storage, Event<T>},
 		Authorship: pallet_authorship::{Pallet, Storage},
-		Configuration: pallet_configuration::{Pallet, Call, Storage, Event<T>},
 	}
 );
 
@@ -216,21 +215,6 @@
 	pub AppPromotionDailyRate: Perbill = Perbill::from_rational(5u32, 10_000);
 	pub const DayRelayBlocks: u32 = 1;
 	pub const LicenceBondIdentifier: [u8; 16] = *b"licenceidentifie";
-}
-
-impl pallet_configuration::Config for Test {
-	type RuntimeEvent = RuntimeEvent;
-	type Currency = Balances;
-	type DefaultCollatorSelectionMaxCollators = MaxCollators;
-	type DefaultCollatorSelectionKickThreshold = KickThreshold;
-	type DefaultCollatorSelectionLicenseBond = LicenseBond;
-	// the following constants we don't care about
-	type DefaultWeightToFeeCoefficient = DefaultWeightToFeeCoefficient;
-	type DefaultMinGasPrice = DefaultMinGasPrice;
-	type MaxXcmAllowedLocations = MaxXcmAllowedLocations;
-	type AppPromotionDailyRate = AppPromotionDailyRate;
-	type DayRelayBlocks = DayRelayBlocks;
-	type WeightInfo = pallet_configuration::weights::SubstrateWeight<Self>;
 }
 
 ord_parameter_types! {
@@ -246,11 +230,7 @@
 pub struct IsRegistered;
 impl ValidatorRegistration<u64> for IsRegistered {
 	fn is_registered(id: &u64) -> bool {
-		if *id == 7u64 {
-			false
-		} else {
-			true
-		}
+		*id != 7u64
 	}
 }
 
@@ -265,6 +245,10 @@
 	type ValidatorIdOf = IdentityCollator;
 	type ValidatorRegistration = IsRegistered;
 	type LicenceBondIdentifier = LicenceBondIdentifier;
+	type Currency = Balances;
+	type DesiredCollators = MaxCollators;
+	type LicenseBond = LicenseBond;
+	type KickThreshold = KickThreshold;
 	type WeightInfo = ();
 }
 
@@ -277,7 +261,11 @@
 
 	let ed = <Test as pallet_balances::Config>::ExistentialDeposit::get();
 
-	let balances = vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100), (33, ed)];
+	let balances: Vec<(u64, u64)> = (1..=<Test as Config>::DesiredCollators::get() as u64 + 1)
+		.map(|i| (i, 100))
+		.chain(core::iter::once((33, ed)))
+		.collect();
+
 	let keys = balances
 		.iter()
 		.map(|&(i, _)| {
modifiedpallets/collator-selection/src/tests.rsdiffbeforeafterboth
--- a/pallets/collator-selection/src/tests.rs
+++ b/pallets/collator-selection/src/tests.rs
@@ -30,19 +30,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use crate as collator_selection;
+use crate::{self as collator_selection, Config};
 use crate::{mock::*, Error};
 use frame_support::{
 	assert_noop, assert_ok,
 	traits::{fungible, GenesisBuild, OnInitialize},
 };
-use frame_system::RawOrigin;
 use sp_runtime::{traits::BadOrigin, TokenError};
-use pallet_configuration::{
-	CollatorSelectionDesiredCollatorsOverride as DesiredCollators,
-	CollatorSelectionKickThresholdOverride as KickThreshold,
-	CollatorSelectionLicenseBondOverride as LicenseBond,
-};
 use scale_info::prelude::*;
 
 fn get_license_and_onboard(account_id: <Test as frame_system::Config>::AccountId) {
@@ -57,9 +51,6 @@
 #[test]
 fn basic_setup_works() {
 	new_test_ext().execute_with(|| {
-		assert_eq!(<DesiredCollators<Test>>::get(), 5);
-		assert_eq!(<LicenseBond<Test>>::get(), 10);
-
 		assert!(CollatorSelection::candidates().is_empty());
 		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
 	});
@@ -120,51 +111,6 @@
 		assert_noop!(
 			CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(RootAccount::get()), 1),
 			Error::<Test>::TooFewInvulnerables
-		);
-	});
-}
-
-#[test]
-fn set_desired_collators_works() {
-	new_test_ext().execute_with(|| {
-		// given
-		assert_eq!(<DesiredCollators<Test>>::get(), 5);
-
-		// can set
-		assert_ok!(Configuration::set_collator_selection_desired_collators(
-			RawOrigin::Root.into(),
-			Some(7)
-		));
-		assert_eq!(<DesiredCollators<Test>>::get(), 7);
-
-		// rejects bad origin
-		assert_noop!(
-			Configuration::set_collator_selection_desired_collators(
-				RuntimeOrigin::signed(1),
-				Some(8)
-			),
-			BadOrigin
-		);
-	});
-}
-
-#[test]
-fn set_license_bond() {
-	new_test_ext().execute_with(|| {
-		// given
-		assert_eq!(<LicenseBond<Test>>::get(), 10);
-
-		// can set
-		assert_ok!(Configuration::set_collator_selection_license_bond(
-			RawOrigin::Root.into(),
-			Some(7)
-		));
-		assert_eq!(<LicenseBond<Test>>::get(), 7);
-
-		// rejects bad origin.
-		assert_noop!(
-			Configuration::set_collator_selection_license_bond(RuntimeOrigin::signed(1), Some(8)),
-			BadOrigin
 		);
 	});
 }
@@ -187,26 +133,19 @@
 #[test]
 fn cannot_onboard_candidate_if_too_many() {
 	new_test_ext().execute_with(|| {
-		// reset desired candidates
-		<pallet_configuration::CollatorSelectionDesiredCollatorsOverride<Test>>::put(0);
-
-		// can still get a license.
-		assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(4)));
-
-		// can't accept anyone anymore.
-		assert_noop!(
-			CollatorSelection::onboard(RuntimeOrigin::signed(4)),
-			Error::<Test>::TooManyCandidates,
-		);
-
-		// reset desired candidates to invulnerables + 1
-		<pallet_configuration::CollatorSelectionDesiredCollatorsOverride<Test>>::put(3);
-		assert_ok!(CollatorSelection::onboard(RuntimeOrigin::signed(4)));
+		// can accept desired value of collators.
+		for c in 3u64..=(<Test as Config>::DesiredCollators::get()).into() {
+			assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(c)));
+			assert_ok!(CollatorSelection::onboard(RuntimeOrigin::signed(c)));
+		}
 
 		// but no more.
-		assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(5)));
+		let undesired_collator = (<Test as Config>::DesiredCollators::get() + 1) as u64;
+		assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(
+			undesired_collator
+		)));
 		assert_noop!(
-			CollatorSelection::onboard(RuntimeOrigin::signed(5)),
+			CollatorSelection::onboard(RuntimeOrigin::signed(undesired_collator)),
 			Error::<Test>::TooManyCandidates,
 		);
 	})
@@ -227,8 +166,8 @@
 fn cannot_obtain_license_if_poor() {
 	new_test_ext().execute_with(|| {
 		let ed = <Test as pallet_balances::Config>::ExistentialDeposit::get();
-		assert_eq!(Balances::free_balance(&3), 100);
-		assert_eq!(Balances::free_balance(&33), ed);
+		assert_eq!(Balances::free_balance(3), 100);
+		assert_eq!(Balances::free_balance(33), ed);
 
 		// works
 		assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(3)));
@@ -266,21 +205,18 @@
 #[test]
 fn becoming_candidate_works() {
 	new_test_ext().execute_with(|| {
-		// given
-		assert_eq!(<DesiredCollators<Test>>::get(), 5);
-		assert_eq!(<LicenseBond<Test>>::get(), 10);
 		assert_eq!(CollatorSelection::candidates(), Vec::new());
 		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
 
 		// take two endowed, non-invulnerables accounts.
-		assert_eq!(Balances::free_balance(&3), 100);
-		assert_eq!(Balances::free_balance(&4), 100);
+		assert_eq!(Balances::free_balance(3), 100);
+		assert_eq!(Balances::free_balance(4), 100);
 
 		get_license_and_onboard(3);
 		get_license_and_onboard(4);
 
-		assert_eq!(Balances::free_balance(&3), 90);
-		assert_eq!(Balances::free_balance(&4), 90);
+		assert_eq!(Balances::free_balance(3), 90);
+		assert_eq!(Balances::free_balance(4), 90);
 
 		assert_eq!(CollatorSelection::candidates().len(), 2);
 	});
@@ -513,7 +449,7 @@
 		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);
 
 		assert_eq!(CollatorSelection::candidates(), vec![4]);
-		assert_eq!(<KickThreshold<Test>>::get(), 10);
+		// assert_eq!(<KickThreshold<Test>>::get(), 10);
 		assert_eq!(CollatorSelection::last_authored_block(4), 20);
 
 		initialize_to_block(30);
modifiedpallets/configuration/CHANGELOG.mddiffbeforeafterboth
--- a/pallets/configuration/CHANGELOG.md
+++ b/pallets/configuration/CHANGELOG.md
@@ -3,7 +3,12 @@
 All notable changes to this project will be documented in this file.
 
 <!-- bureaucrate goes here -->
+## [0.2.0] - 2023-06-27
+
+### Major change
 
+- Architecture fixed: in the configuration of this pallet, bounds on the associated type were determined not by the functional requirements for this pallet itself, but by the pallet that had tight coupling with it.
+
 ## [0.1.3] - 2022-12-29
 
 ### Added
@@ -20,4 +25,4 @@
 
 ### Other changes
 
-- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
\ No newline at end of file
+- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
modifiedpallets/configuration/Cargo.tomldiffbeforeafterboth
--- a/pallets/configuration/Cargo.toml
+++ b/pallets/configuration/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 edition = "2021"
 name = "pallet-configuration"
-version = "0.1.3"
+version = "0.2.0"
 
 [dependencies]
 # Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it.
@@ -22,11 +22,11 @@
 default = ["std"]
 runtime-benchmarks = ["frame-benchmarking"]
 std = [
+	"codec/std",
 	"fp-evm/std",
 	"frame-benchmarking/std",
 	"frame-support/std",
 	"frame-system/std",
-	"codec/std",
 	"sp-arithmetic/std",
 	"sp-core/std",
 	"sp-std/std",
modifiedpallets/configuration/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/configuration/src/benchmarking.rs
+++ b/pallets/configuration/src/benchmarking.rs
@@ -19,7 +19,7 @@
 use super::*;
 use frame_benchmarking::benchmarks;
 use frame_system::{EventRecord, RawOrigin};
-use frame_support::{assert_ok, traits::fungible::Inspect};
+use frame_support::assert_ok;
 
 fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
 	let events = frame_system::Pallet::<T>::events();
@@ -30,7 +30,10 @@
 }
 
 benchmarks! {
-	where_clause { where T: Config }
+	where_clause { where
+		T: Config,
+		T::Balance: From<u32>
+	}
 
 	set_weight_to_fee_coefficient_override {
 		let coeff: u64 = 999;
@@ -60,7 +63,7 @@
 		let max: u32 = 999;
 	}: {
 		assert_ok!(
-			<Pallet<T>>::set_collator_selection_desired_collators(RawOrigin::Root.into(), Some(max.clone()))
+			<Pallet<T>>::set_collator_selection_desired_collators(RawOrigin::Root.into(), Some(max))
 		);
 	}
 	verify {
@@ -68,10 +71,10 @@
 	}
 
 	set_collator_selection_license_bond {
-		let bond_cost: Option<BalanceOf<T>> = Some(T::Currency::minimum_balance() * 10u32.into());
+		let bond_cost: Option<T::Balance> = Some(1000u32.into());
 	}: {
 		assert_ok!(
-			<Pallet<T>>::set_collator_selection_license_bond(RawOrigin::Root.into(), bond_cost.clone())
+			<Pallet<T>>::set_collator_selection_license_bond(RawOrigin::Root.into(), bond_cost)
 		);
 	}
 	verify {
@@ -82,7 +85,7 @@
 		let threshold: Option<T::BlockNumber> = Some(900u32.into());
 	}: {
 		assert_ok!(
-			<Pallet<T>>::set_collator_selection_kick_threshold(RawOrigin::Root.into(), threshold.clone())
+			<Pallet<T>>::set_collator_selection_kick_threshold(RawOrigin::Root.into(), threshold)
 		);
 	}
 	verify {
modifiedpallets/configuration/src/lib.rsdiffbeforeafterboth
--- a/pallets/configuration/src/lib.rs
+++ b/pallets/configuration/src/lib.rs
@@ -22,6 +22,7 @@
 	pallet,
 	weights::{WeightToFeePolynomial, WeightToFeeCoefficients, WeightToFeeCoefficient, Weight},
 	traits::Get,
+	Parameter,
 };
 use codec::{Decode, Encode, MaxEncodedLen};
 use scale_info::TypeInfo;
@@ -42,27 +43,33 @@
 mod pallet {
 	use super::*;
 	use frame_support::{
-		traits::{fungible, Get},
-		pallet_prelude::{StorageValue, ValueQuery, DispatchResult, IsType},
+		traits::{Get},
+		pallet_prelude::{
+			StorageValue, ValueQuery, DispatchResult, IsType, Member, MaybeSerializeDeserialize,
+		},
 		log,
+		dispatch::{Codec, fmt::Debug},
 	};
-	use frame_system::{pallet_prelude::OriginFor, ensure_root, Config as SystemConfig};
-
+	use frame_system::{pallet_prelude::OriginFor, ensure_root};
+	use sp_arithmetic::{FixedPointOperand, traits::AtLeast32BitUnsigned};
 	pub use crate::weights::WeightInfo;
-	pub type BalanceOf<T> =
-		<<T as Config>::Currency as fungible::Inspect<<T as SystemConfig>::AccountId>>::Balance;
 
 	#[pallet::config]
 	pub trait Config: frame_system::Config {
 		/// Overarching event type.
 		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
 
-		type Currency: fungible::Inspect<Self::AccountId>
-			+ fungible::Mutate<Self::AccountId>
-			+ fungible::MutateFreeze<Self::AccountId>
-			+ fungible::InspectHold<Self::AccountId>
-			+ fungible::MutateHold<Self::AccountId>
-			+ fungible::BalancedHold<Self::AccountId>;
+		type Balance: Parameter
+			+ Member
+			+ AtLeast32BitUnsigned
+			+ Codec
+			+ Default
+			+ Copy
+			+ MaybeSerializeDeserialize
+			+ Debug
+			+ MaxEncodedLen
+			+ TypeInfo
+			+ FixedPointOperand;
 
 		#[pallet::constant]
 		type DefaultWeightToFeeCoefficient: Get<u64>;
@@ -79,7 +86,7 @@
 		#[pallet::constant]
 		type DefaultCollatorSelectionMaxCollators: Get<u32>;
 		#[pallet::constant]
-		type DefaultCollatorSelectionLicenseBond: Get<BalanceOf<Self>>;
+		type DefaultCollatorSelectionLicenseBond: Get<Self::Balance>;
 		#[pallet::constant]
 		type DefaultCollatorSelectionKickThreshold: Get<Self::BlockNumber>;
 
@@ -94,7 +101,7 @@
 			desired_collators: Option<u32>,
 		},
 		NewCollatorLicenseBond {
-			bond_cost: Option<BalanceOf<T>>,
+			bond_cost: Option<T::Balance>,
 		},
 		NewCollatorKickThreshold {
 			length_in_blocks: Option<T::BlockNumber>,
@@ -130,7 +137,7 @@
 
 	#[pallet::storage]
 	pub type CollatorSelectionLicenseBondOverride<T: Config> = StorageValue<
-		Value = BalanceOf<T>,
+		Value = T::Balance,
 		QueryKind = ValueQuery,
 		OnEmpty = T::DefaultCollatorSelectionLicenseBond,
 	>;
@@ -221,7 +228,7 @@
 		#[pallet::weight(T::WeightInfo::set_collator_selection_license_bond())]
 		pub fn set_collator_selection_license_bond(
 			origin: OriginFor<T>,
-			amount: Option<BalanceOf<T>>,
+			amount: Option<<T as Config>::Balance>,
 		) -> DispatchResult {
 			ensure_root(origin)?;
 			if let Some(amount) = amount {
modifiedruntime/common/config/pallets/collator_selection.rsdiffbeforeafterboth
--- a/runtime/common/config/pallets/collator_selection.rs
+++ b/runtime/common/config/pallets/collator_selection.rs
@@ -23,7 +23,10 @@
 };
 use sp_runtime::Perbill;
 use up_common::constants::{UNIQUE, MILLIUNIQUE};
-
+use pallet_configuration::{
+	CollatorSelectionKickThresholdOverride, CollatorSelectionLicenseBondOverride,
+	CollatorSelectionDesiredCollatorsOverride,
+};
 parameter_types! {
 	pub const SessionOffset: BlockNumber = 0;
 }
@@ -60,6 +63,9 @@
 	pub const MaxAdditionalFields: u32 = 100;
 	pub const MaxRegistrars: u32 = 20;
 	pub const LicenceBondIdentifier: [u8; 16] = *b"licenceidentifie";
+	pub LicenseBond: Balance =  CollatorSelectionLicenseBondOverride::<Runtime>::get();
+	pub DesiredCollators: u32 = CollatorSelectionDesiredCollatorsOverride::<Runtime>::get();
+	pub KickThreshold: BlockNumber = CollatorSelectionKickThresholdOverride::<Runtime>::get();
 }
 
 impl pallet_identity::Config for Runtime {
@@ -84,6 +90,7 @@
 
 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 TreasuryAccountId = TreasuryAccountId;
@@ -95,4 +102,7 @@
 	type ValidatorRegistration = Session;
 	type WeightInfo = pallet_collator_selection::weights::SubstrateWeight<Runtime>;
 	type LicenceBondIdentifier = LicenceBondIdentifier;
+	type DesiredCollators = DesiredCollators;
+	type LicenseBond = LicenseBond;
+	type KickThreshold = KickThreshold;
 }
modifiedruntime/common/config/pallets/mod.rsdiffbeforeafterboth
--- a/runtime/common/config/pallets/mod.rs
+++ b/runtime/common/config/pallets/mod.rs
@@ -129,7 +129,7 @@
 
 impl pallet_configuration::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
-	type Currency = Balances;
+	type Balance = Balance;
 	type DefaultWeightToFeeCoefficient = ConstU64<{ up_common::constants::WEIGHT_TO_FEE_COEFF }>;
 	type DefaultMinGasPrice = ConstU64<{ up_common::constants::MIN_GAS_PRICE }>;
 	type DefaultCollatorSelectionMaxCollators = MaxCollators;
modifiedtests/src/benchmarks/mintFee/index.tsdiffbeforeafterboth
--- a/tests/src/benchmarks/mintFee/index.ts
+++ b/tests/src/benchmarks/mintFee/index.ts
@@ -360,7 +360,7 @@
           susbstrateReceiver.addressRaw,
           PROPERTIES.slice(0, setup.propertiesNumber),
         )
-        .send({from: ethSigner, gas: 25_000_000});
+        .send({from: ethSigner});
     },
   );