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
--- a/pallets/collator-selection/src/lib.rs
+++ b/pallets/collator-selection/src/lib.rs
@@ -90,6 +90,10 @@
 mod benchmarking;
 pub mod weights;
 
+use frame_support::traits::fungible::Inspect;
+
+type BalanceOf<T> =
+	<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
 #[frame_support::pallet]
 pub mod pallet {
 	use super::*;
@@ -111,11 +115,6 @@
 	use frame_system::pallet_prelude::*;
 	use pallet_session::SessionManager;
 	use sp_runtime::{Perbill, traits::Convert};
-	use pallet_configuration::{
-		CollatorSelectionDesiredCollatorsOverride as DesiredCollators,
-		CollatorSelectionLicenseBondOverride as LicenseBond,
-		CollatorSelectionKickThresholdOverride as KickThreshold, BalanceOf,
-	};
 	use sp_staking::SessionIndex;
 
 	/// A convertor from collators id. Since this pallet does not have stash/controller, this is
@@ -129,9 +128,12 @@
 
 	/// Configure the pallet by specifying the parameters and types on which it depends.
 	#[pallet::config]
-	pub trait Config: frame_system::Config + pallet_configuration::Config {
+	pub trait Config: frame_system::Config {
 		/// Overarching event type.
 		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
+		type Currency: Mutate<Self::AccountId>
+			+ MutateHold<Self::AccountId>
+			+ BalancedHold<Self::AccountId>;
 
 		/// Origin that can dictate updating parameters of this pallet.
 		type UpdateOrigin: EnsureOrigin<Self::RuntimeOrigin>;
@@ -163,7 +165,13 @@
 		type WeightInfo: WeightInfo;
 
 		#[pallet::constant]
-		type LicenceBondIdentifier: Get<<<Self as pallet_configuration::Config>::Currency as InspectHold<Self::AccountId>>::Reason>;
+		type LicenceBondIdentifier: Get<<Self::Currency as InspectHold<Self::AccountId>>::Reason>;
+
+		type DesiredCollators: Get<u32>;
+
+		type LicenseBond: Get<BalanceOf<Self>>;
+
+		type KickThreshold: Get<Self::BlockNumber>;
 	}
 
 	#[pallet::pallet]
@@ -365,7 +373,7 @@
 				Error::<T>::ValidatorNotRegistered
 			);
 
-			let deposit = <LicenseBond<T>>::get();
+			let deposit = T::LicenseBond::get();
 
 			T::Currency::hold(&T::LicenceBondIdentifier::get(), &who, deposit)?;
 			LicenseDepositOf::<T>::insert(who.clone(), deposit);
@@ -396,7 +404,7 @@
 			let length = <Candidates<T>>::decode_len().unwrap_or_default()
 				+ <Invulnerables<T>>::decode_len().unwrap_or_default();
 			ensure!(
-				(length as u32) < <DesiredCollators<T>>::get(),
+				(length as u32) < T::DesiredCollators::get(),
 				Error::<T>::TooManyCandidates
 			);
 			ensure!(
@@ -415,7 +423,7 @@
 						// First authored block is current block plus kick threshold to handle session delay
 						<LastAuthoredBlock<T>>::insert(
 							who.clone(),
-							frame_system::Pallet::<T>::block_number() + <KickThreshold<T>>::get(),
+							frame_system::Pallet::<T>::block_number() + T::KickThreshold::get(),
 						);
 						Ok(candidates.len())
 					}
@@ -574,7 +582,7 @@
 			candidates: BoundedVec<T::AccountId, T::MaxCollators>,
 		) -> BoundedVec<T::AccountId, T::MaxCollators> {
 			let now = frame_system::Pallet::<T>::block_number();
-			let kick_threshold = <KickThreshold<T>>::get();
+			let kick_threshold = T::KickThreshold::get();
 			candidates
 				.into_iter()
 				.filter_map(|c| {
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
after · pallets/configuration/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#![cfg_attr(not(feature = "std"), no_std)]1819use core::marker::PhantomData;2021use frame_support::{22	pallet,23	weights::{WeightToFeePolynomial, WeightToFeeCoefficients, WeightToFeeCoefficient, Weight},24	traits::Get,25	Parameter,26};27use codec::{Decode, Encode, MaxEncodedLen};28use scale_info::TypeInfo;29use sp_arithmetic::{30	per_things::{Perbill, PerThing},31	traits::{BaseArithmetic, Unsigned},32};33use smallvec::smallvec;3435pub use pallet::*;36use sp_core::U256;3738#[cfg(feature = "runtime-benchmarks")]39mod benchmarking;40pub mod weights;4142#[pallet]43mod pallet {44	use super::*;45	use frame_support::{46		traits::{Get},47		pallet_prelude::{48			StorageValue, ValueQuery, DispatchResult, IsType, Member, MaybeSerializeDeserialize,49		},50		log,51		dispatch::{Codec, fmt::Debug},52	};53	use frame_system::{pallet_prelude::OriginFor, ensure_root};54	use sp_arithmetic::{FixedPointOperand, traits::AtLeast32BitUnsigned};55	pub use crate::weights::WeightInfo;5657	#[pallet::config]58	pub trait Config: frame_system::Config {59		/// Overarching event type.60		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;6162		type Balance: Parameter63			+ Member64			+ AtLeast32BitUnsigned65			+ Codec66			+ Default67			+ Copy68			+ MaybeSerializeDeserialize69			+ Debug70			+ MaxEncodedLen71			+ TypeInfo72			+ FixedPointOperand;7374		#[pallet::constant]75		type DefaultWeightToFeeCoefficient: Get<u64>;76		#[pallet::constant]77		type DefaultMinGasPrice: Get<u64>;7879		#[pallet::constant]80		type MaxXcmAllowedLocations: Get<u32>;81		#[pallet::constant]82		type AppPromotionDailyRate: Get<Perbill>;83		#[pallet::constant]84		type DayRelayBlocks: Get<Self::BlockNumber>;8586		#[pallet::constant]87		type DefaultCollatorSelectionMaxCollators: Get<u32>;88		#[pallet::constant]89		type DefaultCollatorSelectionLicenseBond: Get<Self::Balance>;90		#[pallet::constant]91		type DefaultCollatorSelectionKickThreshold: Get<Self::BlockNumber>;9293		/// The weight information of this pallet.94		type WeightInfo: WeightInfo;95	}9697	#[pallet::event]98	#[pallet::generate_deposit(pub(super) fn deposit_event)]99	pub enum Event<T: Config> {100		NewDesiredCollators {101			desired_collators: Option<u32>,102		},103		NewCollatorLicenseBond {104			bond_cost: Option<T::Balance>,105		},106		NewCollatorKickThreshold {107			length_in_blocks: Option<T::BlockNumber>,108		},109	}110111	#[pallet::error]112	pub enum Error<T> {113		InconsistentConfiguration,114	}115116	#[pallet::storage]117	pub type WeightToFeeCoefficientOverride<T: Config> = StorageValue<118		Value = u64,119		QueryKind = ValueQuery,120		OnEmpty = T::DefaultWeightToFeeCoefficient,121	>;122123	#[pallet::storage]124	pub type MinGasPriceOverride<T: Config> =125		StorageValue<Value = u64, QueryKind = ValueQuery, OnEmpty = T::DefaultMinGasPrice>;126127	#[pallet::storage]128	pub type AppPromomotionConfigurationOverride<T: Config> =129		StorageValue<Value = AppPromotionConfiguration<T::BlockNumber>, QueryKind = ValueQuery>;130131	#[pallet::storage]132	pub type CollatorSelectionDesiredCollatorsOverride<T: Config> = StorageValue<133		Value = u32,134		QueryKind = ValueQuery,135		OnEmpty = T::DefaultCollatorSelectionMaxCollators,136	>;137138	#[pallet::storage]139	pub type CollatorSelectionLicenseBondOverride<T: Config> = StorageValue<140		Value = T::Balance,141		QueryKind = ValueQuery,142		OnEmpty = T::DefaultCollatorSelectionLicenseBond,143	>;144145	#[pallet::storage]146	pub type CollatorSelectionKickThresholdOverride<T: Config> = StorageValue<147		Value = T::BlockNumber,148		QueryKind = ValueQuery,149		OnEmpty = T::DefaultCollatorSelectionKickThreshold,150	>;151152	#[pallet::call]153	impl<T: Config> Pallet<T> {154		#[pallet::call_index(0)]155		#[pallet::weight(T::WeightInfo::set_weight_to_fee_coefficient_override())]156		pub fn set_weight_to_fee_coefficient_override(157			origin: OriginFor<T>,158			coeff: Option<u64>,159		) -> DispatchResult {160			ensure_root(origin)?;161			if let Some(coeff) = coeff {162				<WeightToFeeCoefficientOverride<T>>::set(coeff);163			} else {164				<WeightToFeeCoefficientOverride<T>>::kill();165			}166			Ok(())167		}168169		#[pallet::call_index(1)]170		#[pallet::weight(T::WeightInfo::set_min_gas_price_override())]171		pub fn set_min_gas_price_override(172			origin: OriginFor<T>,173			coeff: Option<u64>,174		) -> DispatchResult {175			ensure_root(origin)?;176			if let Some(coeff) = coeff {177				<MinGasPriceOverride<T>>::set(coeff);178			} else {179				<MinGasPriceOverride<T>>::kill();180			}181			Ok(())182		}183184		#[pallet::call_index(3)]185		#[pallet::weight(T::WeightInfo::set_app_promotion_configuration_override())]186		pub fn set_app_promotion_configuration_override(187			origin: OriginFor<T>,188			mut configuration: AppPromotionConfiguration<T::BlockNumber>,189		) -> DispatchResult {190			ensure_root(origin)?;191			if configuration.interval_income.is_some() {192				return Err(<Error<T>>::InconsistentConfiguration.into());193			}194195			configuration.interval_income = configuration.recalculation_interval.map(|b| {196				Perbill::from_rational(b, T::DayRelayBlocks::get())197					* T::AppPromotionDailyRate::get()198			});199200			<AppPromomotionConfigurationOverride<T>>::set(configuration);201202			Ok(())203		}204205		#[pallet::call_index(4)]206		#[pallet::weight(T::WeightInfo::set_collator_selection_desired_collators())]207		pub fn set_collator_selection_desired_collators(208			origin: OriginFor<T>,209			max: Option<u32>,210		) -> DispatchResult {211			ensure_root(origin)?;212			if let Some(max) = max {213				// we trust origin calls, this is just a for more accurate benchmarking214				if max > T::DefaultCollatorSelectionMaxCollators::get() {215					log::warn!("max > T::DefaultCollatorSelectionMaxCollators; you might need to run benchmarks again");216				}217				<CollatorSelectionDesiredCollatorsOverride<T>>::set(max);218			} else {219				<CollatorSelectionDesiredCollatorsOverride<T>>::kill();220			}221			Self::deposit_event(Event::NewDesiredCollators {222				desired_collators: max,223			});224			Ok(())225		}226227		#[pallet::call_index(5)]228		#[pallet::weight(T::WeightInfo::set_collator_selection_license_bond())]229		pub fn set_collator_selection_license_bond(230			origin: OriginFor<T>,231			amount: Option<<T as Config>::Balance>,232		) -> DispatchResult {233			ensure_root(origin)?;234			if let Some(amount) = amount {235				<CollatorSelectionLicenseBondOverride<T>>::set(amount);236			} else {237				<CollatorSelectionLicenseBondOverride<T>>::kill();238			}239			Self::deposit_event(Event::NewCollatorLicenseBond { bond_cost: amount });240			Ok(())241		}242243		#[pallet::call_index(6)]244		#[pallet::weight(T::WeightInfo::set_collator_selection_kick_threshold())]245		pub fn set_collator_selection_kick_threshold(246			origin: OriginFor<T>,247			threshold: Option<T::BlockNumber>,248		) -> DispatchResult {249			ensure_root(origin)?;250			if let Some(threshold) = threshold {251				<CollatorSelectionKickThresholdOverride<T>>::set(threshold);252			} else {253				<CollatorSelectionKickThresholdOverride<T>>::kill();254			}255			Self::deposit_event(Event::NewCollatorKickThreshold {256				length_in_blocks: threshold,257			});258			Ok(())259		}260	}261262	#[pallet::pallet]263	pub struct Pallet<T>(_);264}265266pub struct WeightToFee<T, B>(PhantomData<(T, B)>);267268impl<T, B> WeightToFeePolynomial for WeightToFee<T, B>269where270	T: Config,271	B: BaseArithmetic + From<u32> + From<u64> + Copy + Unsigned,272{273	type Balance = B;274275	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {276		smallvec!(WeightToFeeCoefficient {277			coeff_integer: (<WeightToFeeCoefficientOverride<T>>::get() / Perbill::ACCURACY as u64)278				.into(),279			coeff_frac: Perbill::from_parts(280				(<WeightToFeeCoefficientOverride<T>>::get() % Perbill::ACCURACY as u64) as u32281			),282			negative: false,283			degree: 1,284		})285	}286}287288pub struct FeeCalculator<T>(PhantomData<T>);289impl<T: Config> fp_evm::FeeCalculator for FeeCalculator<T> {290	fn min_gas_price() -> (U256, Weight) {291		(292			<MinGasPriceOverride<T>>::get().into(),293			T::DbWeight::get().reads(1),294		)295	}296}297298#[derive(Encode, Decode, Clone, Debug, Default, TypeInfo, MaxEncodedLen, PartialEq, PartialOrd)]299pub struct AppPromotionConfiguration<BlockNumber> {300	/// In relay blocks.301	pub recalculation_interval: Option<BlockNumber>,302	/// In parachain blocks.303	pub pending_interval: Option<BlockNumber>,304	/// Value for `RecalculationInterval` based on 0.05% per 24h.305	pub interval_income: Option<Perbill>,306	/// Maximum allowable number of stakers calculated per call of the `app-promotion::PayoutStakers` extrinsic.307	pub max_stakers_per_calculation: Option<u8>,308}
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});
     },
   );