difftreelog
Merge branch 'feature/switch-from-currecy-trait-to-fungible-v2' into feature/update-polkadot-v0.9.42
in: master
7 files changed
pallets/collator-selection/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/collator-selection/src/benchmarking.rs
+++ b/pallets/collator-selection/src/benchmarking.rs
@@ -40,7 +40,11 @@
use frame_support::{
assert_ok,
codec::Decode,
- traits::{Currency, EnsureOrigin, Get},
+ traits::{
+ EnsureOrigin,
+ fungible::{Inspect, Mutate},
+ Get,
+ },
};
use frame_system::{EventRecord, RawOrigin};
use pallet_authorship::EventHandler;
@@ -78,7 +82,7 @@
) -> T::AccountId {
let user = account(string, n, SEED);
let balance = balance_unit::<T>() * balance_factor.into();
- let _ = T::Currency::make_free_balance_be(&user, balance);
+ let _ = T::Currency::set_balance(&user, balance);
user
}
@@ -137,7 +141,7 @@
);
for who in candidates {
- T::Currency::make_free_balance_be(&who, <LicenseBond<T>>::get() * 2u32.into());
+ T::Currency::set_balance(&who, <LicenseBond<T>>::get() * 2u32.into());
<CollatorSelection<T>>::get_license(RawOrigin::Signed(who.clone()).into()).unwrap();
<CollatorSelection<T>>::onboard(RawOrigin::Signed(who).into()).unwrap();
}
@@ -153,14 +157,14 @@
);
for who in candidates {
- T::Currency::make_free_balance_be(&who, <LicenseBond<T>>::get() * 2u32.into());
+ T::Currency::set_balance(&who, <LicenseBond<T>>::get() * 2u32.into());
<CollatorSelection<T>>::get_license(RawOrigin::Signed(who.clone()).into()).unwrap();
}
}
/// `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>() -> <T::Currency as Currency<T::AccountId>>::Balance {
+fn balance_unit<T: Config>() -> BalanceOf<T> {
200u32.into()
}
@@ -168,7 +172,9 @@
const INITIAL_INVULNERABLES: u32 = 2;
benchmarks! {
- where_clause { where T: pallet_authorship::Config + session::Config + configuration::Config }
+ where_clause { where
+ T: pallet_authorship::Config + session::Config + configuration::Config
+ }
// todo:collator this and all the following do not work for some reason, going all the way up to 10 in length
// Both invulnerables and candidates count together against MaxCollators.
@@ -182,7 +188,7 @@
let new_invulnerable: T::AccountId = whitelisted_caller();
let bond: BalanceOf<T> = balance_unit::<T>() * 2u32.into();
- T::Currency::make_free_balance_be(&new_invulnerable, bond.clone());
+ T::Currency::set_balance(&new_invulnerable, bond.clone());
<session::Pallet<T>>::set_keys(
RawOrigin::Signed(new_invulnerable.clone()).into(),
@@ -227,7 +233,7 @@
let caller: T::AccountId = whitelisted_caller();
let bond: BalanceOf<T> = balance_unit::<T>() * 2u32.into();
- T::Currency::make_free_balance_be(&caller, bond.clone());
+ T::Currency::set_balance(&caller, bond.clone());
<session::Pallet<T>>::set_keys(
RawOrigin::Signed(caller.clone()).into(),
@@ -253,7 +259,7 @@
let caller: T::AccountId = whitelisted_caller();
let bond: BalanceOf<T> = balance_unit::<T>() * 2u32.into();
- T::Currency::make_free_balance_be(&caller, bond.clone());
+ T::Currency::set_balance(&caller, bond.clone());
let origin = RawOrigin::Signed(caller.clone());
@@ -329,7 +335,7 @@
// worst case is paying a non-existing candidate account.
note_author {
<LicenseBond<T>>::put(balance_unit::<T>());
- T::Currency::make_free_balance_be(
+ T::Currency::set_balance(
&<CollatorSelection<T>>::account_id(),
balance_unit::<T>() * 4u32.into(),
);
@@ -337,11 +343,11 @@
let new_block: T::BlockNumber = 10u32.into();
frame_system::Pallet::<T>::set_block_number(new_block);
- assert!(T::Currency::free_balance(&author) == 0u32.into());
+ assert!(T::Currency::balance(&author) == 0u32.into());
}: {
<CollatorSelection<T> as EventHandler<_, _>>::note_author(author.clone())
} verify {
- assert!(T::Currency::free_balance(&author) > 0u32.into());
+ assert!(T::Currency::balance(&author) > 0u32.into());
assert_eq!(frame_system::Pallet::<T>::block_number(), new_block);
}
pallets/collator-selection/src/lib.rsdiffbeforeafterboth--- a/pallets/collator-selection/src/lib.rs
+++ b/pallets/collator-selection/src/lib.rs
@@ -92,6 +92,7 @@
#[frame_support::pallet]
pub mod pallet {
+ use super::*;
pub use crate::weights::WeightInfo;
use core::ops::Div;
use frame_support::{
@@ -100,8 +101,10 @@
pallet_prelude::*,
sp_runtime::traits::{AccountIdConversion, CheckedSub, Saturating, Zero},
traits::{
- Currency, EnsureOrigin, ExistenceRequirement::KeepAlive, ReservableCurrency,
+ EnsureOrigin,
+ fungible::{Balanced, BalancedHold, Inspect, InspectHold, Mutate, MutateHold},
ValidatorRegistration,
+ tokens::{Precision, Preservation},
},
BoundedVec, PalletId,
};
@@ -158,6 +161,9 @@
/// The weight information of this pallet.
type WeightInfo: WeightInfo;
+
+ #[pallet::constant]
+ type LicenceBondIdentifier: Get<<<Self as pallet_configuration::Config>::Currency as InspectHold<Self::AccountId>>::Reason>;
}
#[pallet::pallet]
@@ -361,7 +367,7 @@
let deposit = <LicenseBond<T>>::get();
- T::Currency::reserve(&who, deposit)?;
+ T::Currency::hold(&T::LicenceBondIdentifier::get(), &who, deposit)?;
LicenseDepositOf::<T>::insert(who.clone(), deposit);
Self::deposit_event(Event::LicenseObtained {
@@ -523,17 +529,24 @@
let slashed = T::SlashRatio::get() * deposit;
let remaining = deposit - slashed;
- let (imbalance, _) = T::Currency::slash_reserved(who, slashed);
+ let (imbalance, _) =
+ T::Currency::slash(&T::LicenceBondIdentifier::get(), who, slashed);
//T::Currency::unreserve(who, remaining);
deposit_returned = remaining;
- T::Currency::resolve_creating(&T::TreasuryAccountId::get(), imbalance);
+ T::Currency::resolve(&T::TreasuryAccountId::get(), imbalance)
+ .map_err(|_| DispatchError::Other("Failed to deposit imbalance"))?;
} else {
//T::Currency::unreserve(who, deposit);
deposit_returned = deposit;
}
- T::Currency::unreserve(who, deposit_returned);
+ T::Currency::release(
+ &T::LicenceBondIdentifier::get(),
+ who,
+ deposit_returned,
+ Precision::Exact,
+ )?;
Ok(())
} else {
Err(Error::<T>::NoLicense.into())
@@ -594,12 +607,12 @@
fn note_author(author: T::AccountId) {
let pot = Self::account_id();
// assumes an ED will be sent to pot.
- let reward = T::Currency::free_balance(&pot)
+ let reward = T::Currency::balance(&pot)
.checked_sub(&T::Currency::minimum_balance())
.unwrap_or_else(Zero::zero)
.div(2u32.into());
// `reward` is half of pot account minus ED, this should never fail.
- let _success = T::Currency::transfer(&pot, &author, reward, KeepAlive);
+ let _success = T::Currency::transfer(&pot, &author, reward, Preservation::Preserve);
debug_assert!(_success.is_ok());
<LastAuthoredBlock<T>>::insert(author, frame_system::Pallet::<T>::block_number());
pallets/collator-selection/src/tests.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/>.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.3233use crate as collator_selection;34use crate::{mock::*, Error};35use frame_support::{36 assert_noop, assert_ok,37 traits::{Currency, GenesisBuild, OnInitialize},38};39use frame_system::RawOrigin;40use pallet_balances::Error as BalancesError;41use sp_runtime::traits::BadOrigin;42use pallet_configuration::{43 CollatorSelectionDesiredCollatorsOverride as DesiredCollators,44 CollatorSelectionKickThresholdOverride as KickThreshold,45 CollatorSelectionLicenseBondOverride as LicenseBond,46};4748fn get_license_and_onboard(account_id: <Test as frame_system::Config>::AccountId) {49 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(50 account_id51 )));52 assert_ok!(CollatorSelection::onboard(RuntimeOrigin::signed(53 account_id54 )));55}5657#[test]58fn basic_setup_works() {59 new_test_ext().execute_with(|| {60 assert_eq!(<DesiredCollators<Test>>::get(), 5);61 assert_eq!(<LicenseBond<Test>>::get(), 10);6263 assert!(CollatorSelection::candidates().is_empty());64 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);65 });66}6768#[test]69fn it_should_add_invulnerables() {70 new_test_ext().execute_with(|| {71 assert_ok!(CollatorSelection::add_invulnerable(72 RuntimeOrigin::signed(RootAccount::get()),73 174 ));75 assert_ok!(CollatorSelection::add_invulnerable(76 RuntimeOrigin::signed(RootAccount::get()),77 278 ));79 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);8081 // cannot set with non-root.82 assert_noop!(83 CollatorSelection::add_invulnerable(RuntimeOrigin::signed(1), 3),84 BadOrigin85 );8687 // cannot set invulnerables without associated validator keys88 assert_noop!(89 CollatorSelection::add_invulnerable(RuntimeOrigin::signed(RootAccount::get()), 7),90 Error::<Test>::ValidatorNotRegistered91 );92 });93}9495#[test]96fn it_should_remove_invulnerables() {97 new_test_ext().execute_with(|| {98 assert_ok!(CollatorSelection::add_invulnerable(99 RuntimeOrigin::signed(RootAccount::get()),100 1101 ));102 assert_ok!(CollatorSelection::add_invulnerable(103 RuntimeOrigin::signed(RootAccount::get()),104 2105 ));106107 // cannot remove with non-root.108 assert_noop!(109 CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(1), 3),110 BadOrigin111 );112113 assert_ok!(CollatorSelection::remove_invulnerable(114 RuntimeOrigin::signed(RootAccount::get()),115 2116 ));117 assert_eq!(CollatorSelection::invulnerables(), vec![1]);118119 // cannot remove an invulnerable if there would be 0 invulnerables.120 assert_noop!(121 CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(RootAccount::get()), 1),122 Error::<Test>::TooFewInvulnerables123 );124 });125}126127#[test]128fn set_desired_collators_works() {129 new_test_ext().execute_with(|| {130 // given131 assert_eq!(<DesiredCollators<Test>>::get(), 5);132133 // can set134 assert_ok!(Configuration::set_collator_selection_desired_collators(135 RawOrigin::Root.into(),136 Some(7)137 ));138 assert_eq!(<DesiredCollators<Test>>::get(), 7);139140 // rejects bad origin141 assert_noop!(142 Configuration::set_collator_selection_desired_collators(143 RuntimeOrigin::signed(1),144 Some(8)145 ),146 BadOrigin147 );148 });149}150151#[test]152fn set_license_bond() {153 new_test_ext().execute_with(|| {154 // given155 assert_eq!(<LicenseBond<Test>>::get(), 10);156157 // can set158 assert_ok!(Configuration::set_collator_selection_license_bond(159 RawOrigin::Root.into(),160 Some(7)161 ));162 assert_eq!(<LicenseBond<Test>>::get(), 7);163164 // rejects bad origin.165 assert_noop!(166 Configuration::set_collator_selection_license_bond(RuntimeOrigin::signed(1), Some(8)),167 BadOrigin168 );169 });170}171172#[test]173fn cannot_onboard_candidate_with_no_license() {174 new_test_ext().execute_with(|| {175 // can't onboard a candidate who did not get a license.176 assert_noop!(177 CollatorSelection::onboard(RuntimeOrigin::signed(3)),178 Error::<Test>::NoLicense,179 );180181 // but give it a license and welcome aboard.182 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(3)));183 assert_ok!(CollatorSelection::onboard(RuntimeOrigin::signed(3)));184 })185}186187#[test]188fn cannot_onboard_candidate_if_too_many() {189 new_test_ext().execute_with(|| {190 // reset desired candidates191 <pallet_configuration::CollatorSelectionDesiredCollatorsOverride<Test>>::put(0);192193 // can still get a license.194 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(4)));195196 // can't accept anyone anymore.197 assert_noop!(198 CollatorSelection::onboard(RuntimeOrigin::signed(4)),199 Error::<Test>::TooManyCandidates,200 );201202 // reset desired candidates to invulnerables + 1203 <pallet_configuration::CollatorSelectionDesiredCollatorsOverride<Test>>::put(3);204 assert_ok!(CollatorSelection::onboard(RuntimeOrigin::signed(4)));205206 // but no more.207 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(5)));208 assert_noop!(209 CollatorSelection::onboard(RuntimeOrigin::signed(5)),210 Error::<Test>::TooManyCandidates,211 );212 })213}214215#[test]216fn cannot_obtain_license_if_keys_not_registered() {217 new_test_ext().execute_with(|| {218 // can't 7 because keys not registered.219 assert_noop!(220 CollatorSelection::get_license(RuntimeOrigin::signed(7)),221 Error::<Test>::ValidatorNotRegistered222 );223 })224}225226#[test]227fn cannot_obtain_license_if_poor() {228 new_test_ext().execute_with(|| {229 assert_eq!(Balances::free_balance(&3), 100);230 assert_eq!(Balances::free_balance(&33), 0);231232 // works233 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(3)));234235 // poor236 assert_noop!(237 CollatorSelection::get_license(RuntimeOrigin::signed(33)),238 BalancesError::<Test>::InsufficientBalance,239 );240 });241}242243#[test]244fn cannot_onboard_dupe_candidate() {245 new_test_ext().execute_with(|| {246 // can add 3 as candidate247 get_license_and_onboard(3);248 assert_eq!(CollatorSelection::license_deposit_of(3), 10);249 assert_eq!(CollatorSelection::candidates(), vec![3]);250 assert_eq!(CollatorSelection::last_authored_block(3), 10);251 assert_eq!(Balances::free_balance(3), 90);252253 // but no more254 assert_noop!(255 CollatorSelection::get_license(RuntimeOrigin::signed(3)),256 Error::<Test>::AlreadyHoldingLicense,257 );258 assert_noop!(259 CollatorSelection::onboard(RuntimeOrigin::signed(3)),260 Error::<Test>::AlreadyCandidate,261 );262 })263}264265#[test]266fn becoming_candidate_works() {267 new_test_ext().execute_with(|| {268 // given269 assert_eq!(<DesiredCollators<Test>>::get(), 5);270 assert_eq!(<LicenseBond<Test>>::get(), 10);271 assert_eq!(CollatorSelection::candidates(), Vec::new());272 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);273274 // take two endowed, non-invulnerables accounts.275 assert_eq!(Balances::free_balance(&3), 100);276 assert_eq!(Balances::free_balance(&4), 100);277278 get_license_and_onboard(3);279 get_license_and_onboard(4);280281 assert_eq!(Balances::free_balance(&3), 90);282 assert_eq!(Balances::free_balance(&4), 90);283284 assert_eq!(CollatorSelection::candidates().len(), 2);285 });286}287288#[test]289fn cannot_become_candidate_if_invulnerable() {290 new_test_ext().execute_with(|| {291 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);292293 // can obtain a license even if is invulnerable.294 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(1)));295 // but cannot onboard296 assert_noop!(297 CollatorSelection::onboard(RuntimeOrigin::signed(1)),298 Error::<Test>::AlreadyInvulnerable,299 );300301 // get a license and then become invulnerable.302 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(3)));303 assert_ok!(CollatorSelection::add_invulnerable(304 RuntimeOrigin::signed(RootAccount::get()),305 3306 ));307 assert_noop!(308 CollatorSelection::onboard(RuntimeOrigin::signed(3)),309 Error::<Test>::AlreadyInvulnerable,310 );311 })312}313314#[test]315fn can_become_invulnerable_if_candidate() {316 new_test_ext().execute_with(|| {317 // become a candidate and then become invulnerable.318 get_license_and_onboard(3);319 assert_eq!(CollatorSelection::candidates(), vec![3]);320321 assert_ok!(CollatorSelection::add_invulnerable(322 RuntimeOrigin::signed(RootAccount::get()),323 3324 ));325 // should exclude from candidates, but not revoke the license326 assert_eq!(CollatorSelection::candidates(), vec![]);327 assert_eq!(CollatorSelection::license_deposit_of(3), 10);328 assert_eq!(Balances::free_balance(3), 90);329 });330}331332#[test]333fn offboard() {334 new_test_ext().execute_with(|| {335 // register a candidate.336 get_license_and_onboard(3);337 assert_eq!(Balances::free_balance(3), 90);338339 // cannot leave if holds license but not yet candidate.340 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(4)));341 assert_noop!(342 CollatorSelection::offboard(RuntimeOrigin::signed(4)),343 Error::<Test>::NotCandidate344 );345 // cannot leave if does not hold license.346 assert_noop!(347 CollatorSelection::offboard(RuntimeOrigin::signed(5)),348 Error::<Test>::NotCandidate349 );350351 // bond is returned - only after releasing the license352 assert_ok!(CollatorSelection::offboard(RuntimeOrigin::signed(3)));353 assert_eq!(Balances::free_balance(3), 90);354 assert_eq!(CollatorSelection::last_authored_block(3), 0);355 assert_ok!(CollatorSelection::release_license(RuntimeOrigin::signed(3)));356 assert_eq!(Balances::free_balance(3), 100);357 });358}359360#[test]361fn release_license() {362 new_test_ext().execute_with(|| {363 // obtain a license to collate and reserve the bond.364 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(3)));365 assert_eq!(Balances::free_balance(3), 90);366367 // release the license and get the bond back.368 assert_ok!(CollatorSelection::release_license(RuntimeOrigin::signed(3)));369 assert_eq!(Balances::free_balance(3), 100);370371 // register a candidate.372 get_license_and_onboard(3);373 assert_eq!(Balances::free_balance(3), 90);374375 // can release license even if onboarded.376 assert_ok!(CollatorSelection::release_license(RuntimeOrigin::signed(3)));377 assert_eq!(Balances::free_balance(3), 100);378 assert_eq!(CollatorSelection::candidates(), vec![]);379 });380}381382#[test]383fn force_release_license() {384 new_test_ext().execute_with(|| {385 // obtain a license to collate and reserve the bond.386 assert_ok!(CollatorSelection::get_license(RuntimeOrigin::signed(3)));387 assert_eq!(Balances::free_balance(3), 90);388389 // cannot execute the operation as non-root390 assert_noop!(391 CollatorSelection::force_release_license(RuntimeOrigin::signed(3), 3),392 BadOrigin393 );394395 // release the license and get the bond back.396 assert_ok!(CollatorSelection::force_release_license(397 RuntimeOrigin::signed(RootAccount::get()),398 3399 ));400 assert_eq!(Balances::free_balance(3), 100);401402 // register a candidate.403 get_license_and_onboard(3);404 assert_eq!(Balances::free_balance(3), 90);405406 // can release license even if onboarded.407 assert_ok!(CollatorSelection::force_release_license(408 RuntimeOrigin::signed(RootAccount::get()),409 3410 ));411 assert_eq!(Balances::free_balance(3), 100);412 assert_eq!(CollatorSelection::candidates(), vec![]);413 });414}415416#[test]417fn authorship_event_handler() {418 new_test_ext().execute_with(|| {419 // put 100 in the pot + 5 for ED420 Balances::make_free_balance_be(&CollatorSelection::account_id(), 105);421422 // 4 is the default author.423 assert_eq!(Balances::free_balance(4), 100);424 get_license_and_onboard(4);425 // triggers `note_author`426 Authorship::on_initialize(1);427428 assert_eq!(CollatorSelection::candidates(), vec![4]);429 assert_eq!(CollatorSelection::last_authored_block(4), 0);430431 // half of the pot goes to the collator who's the author (4 in tests).432 assert_eq!(Balances::free_balance(4), 140);433 // half + ED stays.434 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 55);435 });436}437438#[test]439fn fees_edgecases() {440 new_test_ext().execute_with(|| {441 // Nothing panics, no reward when no ED in balance442 Authorship::on_initialize(1);443 // put some money into the pot at ED444 Balances::make_free_balance_be(&CollatorSelection::account_id(), 5);445 // 4 is the default author.446 assert_eq!(Balances::free_balance(4), 100);447 get_license_and_onboard(4);448 // triggers `note_author`449 Authorship::on_initialize(1);450451 assert_eq!(CollatorSelection::candidates(), vec![4]);452 assert_eq!(CollatorSelection::last_authored_block(4), 0);453 // Nothing received454 assert_eq!(Balances::free_balance(4), 90);455 // all fee stays456 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 5);457 });458}459460#[test]461fn session_management_works() {462 new_test_ext().execute_with(|| {463 initialize_to_block(1);464465 assert_eq!(SessionChangeBlock::get(), 0);466 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);467468 initialize_to_block(4);469470 assert_eq!(SessionChangeBlock::get(), 0);471 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);472473 // add a new collator474 get_license_and_onboard(5);475476 // session won't see this.477 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);478 // but we have a new candidate.479 assert_eq!(CollatorSelection::candidates().len(), 1);480481 initialize_to_block(10);482 assert_eq!(SessionChangeBlock::get(), 10);483 // pallet-session has 1 session delay; current validators are the same.484 assert_eq!(Session::validators(), vec![1, 2]);485 // queued ones are changed, and now we have 3.486 assert_eq!(Session::queued_keys().len(), 3);487 // session handlers (aura, et. al.) cannot see this yet.488 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);489490 initialize_to_block(20);491 assert_eq!(SessionChangeBlock::get(), 20);492 // changed are now reflected to session handlers.493 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 5]);494 });495}496497#[test]498fn kick_mechanism() {499 new_test_ext().execute_with(|| {500 // add a new collator501 get_license_and_onboard(3);502 get_license_and_onboard(4);503504 initialize_to_block(10);505 assert_eq!(CollatorSelection::candidates().len(), 2);506507 initialize_to_block(20);508 assert_eq!(SessionChangeBlock::get(), 20);509 // 4 authored this block, gets to stay 3 was kicked510 assert_eq!(CollatorSelection::candidates().len(), 1);511 // 3 will be kicked after 1 session delay512 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);513514 assert_eq!(CollatorSelection::candidates(), vec![4]);515 assert_eq!(<KickThreshold<Test>>::get(), 10);516 assert_eq!(CollatorSelection::last_authored_block(4), 20);517518 initialize_to_block(30);519 // 3 gets kicked after 1 session delay520 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 4]);521 // kicked collator gets their funds slashed, the deposit going to treasury522 assert_eq!(Balances::free_balance(3), 90);523 });524}525526#[test]527#[should_panic = "duplicate invulnerables in genesis."]528fn cannot_set_genesis_value_twice() {529 sp_tracing::try_init_simple();530 let mut t = frame_system::GenesisConfig::default()531 .build_storage::<Test>()532 .unwrap();533 let invulnerables = vec![1, 1];534535 let collator_selection = collator_selection::GenesisConfig::<Test> { invulnerables };536 // collator selection must be initialized before session.537 collator_selection.assimilate_storage(&mut t).unwrap();538}pallets/common/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/common/src/benchmarking.rs
+++ b/pallets/common/src/benchmarking.rs
@@ -27,12 +27,12 @@
MAX_PROPERTIES_PER_ITEM,
};
use frame_support::{
- traits::{Currency, Get},
+ traits::{Get, fungible::Balanced, Imbalance, tokens::Precision},
pallet_prelude::ConstU32,
BoundedVec,
};
use core::convert::TryInto;
-use sp_runtime::DispatchError;
+use sp_runtime::{DispatchError, traits::Zero};
const SEED: u32 = 1;
@@ -85,7 +85,12 @@
) -> Result<CollectionId, DispatchError>,
cast: impl FnOnce(CollectionHandle<T>) -> R,
) -> Result<R, DispatchError> {
- <T as Config>::Currency::deposit_creating(&owner.as_sub(), T::CollectionCreationPrice::get());
+ let imbalance = <T as Config>::Currency::deposit(
+ &owner.as_sub(),
+ T::CollectionCreationPrice::get(),
+ Precision::Exact,
+ )?;
+ debug_assert!(imbalance.peek().is_zero());
let name = create_u16_data::<MAX_COLLECTION_NAME_LENGTH>();
let description = create_u16_data::<MAX_COLLECTION_DESCRIPTION_LENGTH>();
let token_prefix = create_data::<MAX_TOKEN_PREFIX_LENGTH>();
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -64,7 +64,11 @@
use frame_support::{
dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Weight, PostDispatchInfo},
ensure,
- traits::{Imbalance, Get, Currency, WithdrawReasons, ExistenceRequirement},
+ traits::{
+ Get,
+ fungible::{Balanced, Debt, Inspect},
+ tokens::{Imbalance, Precision, Preservation},
+ },
dispatch::Pays,
transactional, fail,
};
@@ -85,7 +89,7 @@
pub use pallet::*;
use sp_core::H160;
-use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
+use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, traits::Zero};
#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarking;
@@ -424,7 +428,6 @@
use super::*;
use dispatch::CollectionDispatch;
use frame_support::{Blake2_128Concat, pallet_prelude::*, storage::Key, traits::StorageVersion};
- use frame_support::traits::Currency;
use up_data_structs::{TokenId, mapping::TokenAddressMapping};
use scale_info::TypeInfo;
use weights::WeightInfo;
@@ -440,12 +443,12 @@
type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;
/// Handler of accounts and payment.
- type Currency: Currency<Self::AccountId>;
+ type Currency: Balanced<Self::AccountId> + Inspect<Self::AccountId>;
/// Set price to create a collection.
#[pallet::constant]
type CollectionCreationPrice: Get<
- <<Self as Config>::Currency as Currency<Self::AccountId>>::Balance,
+ <<Self as Config>::Currency as Inspect<Self::AccountId>>::Balance,
>;
/// Dispatcher of operations on collections.
@@ -1112,21 +1115,17 @@
// Take a (non-refundable) deposit of collection creation
{
- let mut imbalance =
- <<<T as Config>::Currency as Currency<T::AccountId>>::PositiveImbalance>::zero();
- imbalance.subsume(
- <<T as Config>::Currency as Currency<T::AccountId>>::deposit_creating(
- &T::TreasuryAccountId::get(),
- T::CollectionCreationPrice::get(),
- ),
- );
- <T as Config>::Currency::settle(
- payer.as_sub(),
- imbalance,
- WithdrawReasons::TRANSFER,
- ExistenceRequirement::KeepAlive,
- )
- .map_err(|_| Error::<T>::NotSufficientFounds)?;
+ let mut imbalance = <Debt<T::AccountId, <T as Config>::Currency>>::zero();
+ imbalance.subsume(<T as Config>::Currency::deposit(
+ &T::TreasuryAccountId::get(),
+ T::CollectionCreationPrice::get(),
+ Precision::Exact,
+ )?);
+ let credit =
+ <T as Config>::Currency::settle(payer.as_sub(), imbalance, Preservation::Preserve)
+ .map_err(|_| Error::<T>::NotSufficientFounds)?;
+
+ debug_assert!(credit.peek().is_zero())
}
<CreatedCollectionCount<T>>::put(created_count);
pallets/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::Currency};
+use frame_support::{assert_ok, traits::fungible::Inspect};
fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
let events = frame_system::Pallet::<T>::events();
@@ -68,7 +68,7 @@
}
set_collator_selection_license_bond {
- let bond_cost: Option<BalanceOf<T>> = Some(T::Currency::minimum_balance() * 10u32.into());
+ let bond_cost: Option<BalanceOf<T>> = Some(T::Balances::minimum_balance() * 10u32.into());
}: {
assert_ok!(
<Pallet<T>>::set_collator_selection_license_bond(RawOrigin::Root.into(), bond_cost.clone())
pallets/configuration/src/lib.rsdiffbeforeafterboth--- a/pallets/configuration/src/lib.rs
+++ b/pallets/configuration/src/lib.rs
@@ -42,7 +42,7 @@
mod pallet {
use super::*;
use frame_support::{
- traits::{Get, ReservableCurrency, Currency},
+ traits::{fungible, Get, ReservableCurrency, Currency},
pallet_prelude::{StorageValue, ValueQuery, DispatchResult, IsType},
log,
};
@@ -50,15 +50,19 @@
pub use crate::weights::WeightInfo;
pub type BalanceOf<T> =
- <<T as Config>::Currency as Currency<<T as SystemConfig>::AccountId>>::Balance;
+ <<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>;
- /// The currency mechanism.
- type Currency: ReservableCurrency<Self::AccountId>;
+ 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>;
#[pallet::constant]
type DefaultWeightToFeeCoefficient: Get<u64>;