diff --git a/substrate/frame/lottery/src/benchmarking.rs b/substrate/frame/lottery/src/benchmarking.rs index 046bc0acbb644..945d7850fa298 100644 --- a/substrate/frame/lottery/src/benchmarking.rs +++ b/substrate/frame/lottery/src/benchmarking.rs @@ -60,7 +60,7 @@ mod benchmarks { #[benchmark] fn buy_ticket() -> Result<(), BenchmarkError> { let caller = whitelisted_caller(); - T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + T::Currency::set_balance(&caller, T::Currency::minimum_balance() * 10u32.into()); setup_lottery::(false)?; // force user to have a long vec of calls participating let set_code_index: CallIndex = Lottery::::call_to_index( @@ -140,18 +140,15 @@ mod benchmarks { setup_lottery::(false)?; let winner = account("winner", 0, 0); // User needs more than min balance to get ticket - T::Currency::make_free_balance_be(&winner, T::Currency::minimum_balance() * 10u32.into()); + T::Currency::set_balance(&winner, T::Currency::minimum_balance() * 10u32.into()); // Make sure lottery account has at least min balance too let lottery_account = Lottery::::account_id(); - T::Currency::make_free_balance_be( - &lottery_account, - T::Currency::minimum_balance() * 10u32.into(), - ); + T::Currency::set_balance(&lottery_account, T::Currency::minimum_balance() * 10u32.into()); // Buy a ticket let call = frame_system::Call::::remark { remark: vec![] }; Lottery::::buy_ticket(RawOrigin::Signed(winner.clone()).into(), Box::new(call.into()))?; // Kill user account for worst case - T::Currency::make_free_balance_be(&winner, 0u32.into()); + T::Currency::set_balance(&winner, 0u32.into()); // Assert that lotto is set up for winner assert_eq!(TicketsCount::::get(), 1); assert!(!Lottery::::pot().1.is_zero()); @@ -169,7 +166,12 @@ mod benchmarks { assert!(crate::Lottery::::get().is_none()); assert_eq!(TicketsCount::::get(), 0); assert_eq!(Lottery::::pot().1, 0u32.into()); - assert!(!T::Currency::free_balance(&winner).is_zero()); + assert!(!T::Currency::reducible_balance( + &winner, + Preservation::Expendable, + Fortitude::Polite + ) + .is_zero()); Ok(()) } @@ -179,18 +181,15 @@ mod benchmarks { setup_lottery::(true)?; let winner = account("winner", 0, 0); // User needs more than min balance to get ticket - T::Currency::make_free_balance_be(&winner, T::Currency::minimum_balance() * 10u32.into()); + T::Currency::set_balance(&winner, T::Currency::minimum_balance() * 10u32.into()); // Make sure lottery account has at least min balance too let lottery_account = Lottery::::account_id(); - T::Currency::make_free_balance_be( - &lottery_account, - T::Currency::minimum_balance() * 10u32.into(), - ); + T::Currency::set_balance(&lottery_account, T::Currency::minimum_balance() * 10u32.into()); // Buy a ticket let call = frame_system::Call::::remark { remark: vec![] }; Lottery::::buy_ticket(RawOrigin::Signed(winner.clone()).into(), Box::new(call.into()))?; // Kill user account for worst case - T::Currency::make_free_balance_be(&winner, 0u32.into()); + T::Currency::set_balance(&winner, 0u32.into()); // Assert that lotto is set up for winner assert_eq!(TicketsCount::::get(), 1); assert!(!Lottery::::pot().1.is_zero()); @@ -209,7 +208,12 @@ mod benchmarks { assert_eq!(LotteryIndex::::get(), 2); assert_eq!(TicketsCount::::get(), 0); assert_eq!(Lottery::::pot().1, 0u32.into()); - assert!(!T::Currency::free_balance(&winner).is_zero()); + assert!(!T::Currency::reducible_balance( + &winner, + Preservation::Expendable, + Fortitude::Polite + ) + .is_zero()); Ok(()) } diff --git a/substrate/frame/lottery/src/lib.rs b/substrate/frame/lottery/src/lib.rs index e8eb7a815205b..d393e00d1cc06 100644 --- a/substrate/frame/lottery/src/lib.rs +++ b/substrate/frame/lottery/src/lib.rs @@ -63,7 +63,11 @@ use frame_support::{ ensure, pallet_prelude::MaxEncodedLen, storage::bounded_vec::BoundedVec, - traits::{Currency, ExistenceRequirement::KeepAlive, Get, Randomness, ReservableCurrency}, + traits::{ + fungible::{Inspect, Mutate}, + tokens::{Fortitude, Preservation}, + Get, Randomness, + }, PalletId, }; pub use pallet::*; @@ -74,7 +78,7 @@ use sp_runtime::{ pub use weights::WeightInfo; type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Inspect<::AccountId>>::Balance; // Any runtime call can be encoded into two bytes which represent the pallet and call index. // We use this to uniquely match someone's incoming call with the calls configured for the lottery. @@ -141,7 +145,7 @@ pub mod pallet { + From>; /// The currency trait. - type Currency: ReservableCurrency; + type Currency: Inspect + Mutate; /// Something that provides randomness in the runtime. type Randomness: Randomness>; @@ -256,7 +260,7 @@ pub mod pallet { &Self::account_id(), &winner, lottery_balance, - KeepAlive, + Preservation::Preserve, ); debug_assert!(res.is_ok()); @@ -371,8 +375,7 @@ pub mod pallet { // Make sure pot exists. let lottery_account = Self::account_id(); if T::Currency::total_balance(&lottery_account).is_zero() { - let _ = - T::Currency::deposit_creating(&lottery_account, T::Currency::minimum_balance()); + let _ = T::Currency::mint_into(&lottery_account, T::Currency::minimum_balance()); } Self::deposit_event(Event::::LotteryStarted); Ok(()) @@ -410,7 +413,7 @@ impl Pallet { fn pot() -> (T::AccountId, BalanceOf) { let account_id = Self::account_id(); let balance = - T::Currency::free_balance(&account_id).saturating_sub(T::Currency::minimum_balance()); + T::Currency::reducible_balance(&account_id, Preservation::Preserve, Fortitude::Polite); (account_id, balance) } @@ -467,7 +470,12 @@ impl Pallet { } participating_calls.try_push(call_index).map_err(|_| Error::::TooManyCalls)?; // Check user has enough funds and send it to the Lottery account. - T::Currency::transfer(caller, &Self::account_id(), config.price, KeepAlive)?; + T::Currency::transfer( + caller, + &Self::account_id(), + config.price, + Preservation::Preserve, + )?; // Create a new ticket. TicketsCount::::put(new_ticket_count); Tickets::::insert(ticket_count, caller.clone()); diff --git a/substrate/frame/lottery/src/tests.rs b/substrate/frame/lottery/src/tests.rs index 119be5df49250..5da4f8c5161de 100644 --- a/substrate/frame/lottery/src/tests.rs +++ b/substrate/frame/lottery/src/tests.rs @@ -53,14 +53,20 @@ fn basic_end_to_end_works() { assert_ok!(Lottery::start_lottery(RuntimeOrigin::root(), price, length, delay, true)); assert!(crate::Lottery::::get().is_some()); - assert_eq!(Balances::free_balance(&1), 100); + assert_eq!( + Balances::reducible_balance(&1, Preservation::Expendable, Fortitude::Polite), + 100 + ); let call = Box::new(RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 20, })); assert_ok!(Lottery::buy_ticket(RuntimeOrigin::signed(1), call.clone())); // 20 from the transfer, 10 from buying a ticket - assert_eq!(Balances::free_balance(&1), 100 - 20 - 10); + assert_eq!( + Balances::reducible_balance(&1, Preservation::Expendable, Fortitude::Polite), + 100 - 20 - 10 + ); assert_eq!(Participants::::get(&1).1.len(), 1); assert_eq!(TicketsCount::::get(), 1); // 1 owns the 0 ticket @@ -81,7 +87,10 @@ fn basic_end_to_end_works() { // Go to payout System::run_to_block::(25); // User 1 wins - assert_eq!(Balances::free_balance(&1), 70 + 40); + assert_eq!( + Balances::reducible_balance(&1, Preservation::Expendable, Fortitude::Polite), + 70 + 40 + ); // Lottery is reset and restarted assert_eq!(TicketsCount::::get(), 0); assert_eq!(LotteryIndex::::get(), 2); @@ -210,7 +219,10 @@ fn buy_ticket_works_as_simple_passthrough() { })); // This is just a basic transfer then assert_ok!(Lottery::buy_ticket(RuntimeOrigin::signed(1), call.clone())); - assert_eq!(Balances::free_balance(&1), 100 - 20); + assert_eq!( + Balances::reducible_balance(&1, Preservation::Expendable, Fortitude::Polite), + 100 - 20 + ); assert_eq!(TicketsCount::::get(), 0); // Lottery is set up, but too expensive to enter, so `do_buy_ticket` fails. @@ -223,7 +235,10 @@ fn buy_ticket_works_as_simple_passthrough() { // Ticket price of 60 would kill the user's account assert_ok!(Lottery::start_lottery(RuntimeOrigin::root(), 60, 10, 5, false)); assert_ok!(Lottery::buy_ticket(RuntimeOrigin::signed(1), call.clone())); - assert_eq!(Balances::free_balance(&1), 100 - 20 - 20); + assert_eq!( + Balances::reducible_balance(&1, Preservation::Expendable, Fortitude::Polite), + 100 - 20 - 20 + ); assert_eq!(TicketsCount::::get(), 0); // If call would fail, the whole thing still fails the same @@ -419,9 +434,23 @@ fn start_lottery_will_create_account() { let length = 20; let delay = 5; - assert_eq!(Balances::total_balance(&Lottery::account_id()), 0); + assert_eq!( + Balances::reducible_balance( + &Lottery::account_id(), + Preservation::Expendable, + Fortitude::Polite + ), + 0 + ); assert_ok!(Lottery::start_lottery(RuntimeOrigin::root(), price, length, delay, false)); - assert_eq!(Balances::total_balance(&Lottery::account_id()), 1); + assert_eq!( + Balances::reducible_balance( + &Lottery::account_id(), + Preservation::Expendable, + Fortitude::Polite + ), + 1 + ); }); }