diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 05f75b14b9..52eb5e42bd 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1019,7 +1019,7 @@ impl pallet_mmr::Config for Runtime { parameter_types! { pub const LotteryPalletId: PalletId = PalletId(*b"py/lotto"); - pub const MaxCalls: usize = 10; + pub const MaxCalls: u32 = 10; pub const MaxGenerateRandom: u32 = 10; } diff --git a/substrate/frame/lottery/src/benchmarking.rs b/substrate/frame/lottery/src/benchmarking.rs index a2b8946ecc..8fe91088b8 100644 --- a/substrate/frame/lottery/src/benchmarking.rs +++ b/substrate/frame/lottery/src/benchmarking.rs @@ -22,11 +22,11 @@ use super::*; use frame_system::RawOrigin; -use frame_support::traits::{OnInitialize, UnfilteredDispatchable}; +use frame_support::traits::{EnsureOrigin, OnInitialize, UnfilteredDispatchable}; use frame_benchmarking::{benchmarks, account, whitelisted_caller, impl_benchmark_test_suite}; use sp_runtime::traits::{Bounded, Zero}; -use crate::Module as Lottery; +use crate::Pallet as Lottery; // Set up and start a lottery fn setup_lottery(repeat: bool) -> Result<(), &'static str> { @@ -36,7 +36,7 @@ fn setup_lottery(repeat: bool) -> Result<(), &'static str> { // Calls will be maximum length... let mut calls = vec![ frame_system::Call::::set_code(vec![]).into(); - T::MaxCalls::get().saturating_sub(1) + T::MaxCalls::get().saturating_sub(1) as usize ]; // Last call will be the match for worst case scenario. calls.push(frame_system::Call::::remark(vec![]).into()); @@ -56,10 +56,10 @@ benchmarks! { &frame_system::Call::::set_code(vec![]).into() )?; let already_called: (u32, Vec) = ( - LotteryIndex::get(), + LotteryIndex::::get(), vec![ set_code_index; - T::MaxCalls::get().saturating_sub(1) + T::MaxCalls::get().saturating_sub(1) as usize ], ); Participants::::insert(&caller, already_called); @@ -67,7 +67,7 @@ benchmarks! { let call = frame_system::Call::::remark(vec![]); }: _(RawOrigin::Signed(caller), Box::new(call.into())) verify { - assert_eq!(TicketsCount::get(), 1); + assert_eq!(TicketsCount::::get(), 1); } set_calls { @@ -76,11 +76,11 @@ benchmarks! { let call = Call::::set_calls(calls); let origin = T::ManagerOrigin::successful_origin(); - assert!(CallIndices::get().is_empty()); + assert!(CallIndices::::get().is_empty()); }: { call.dispatch_bypass_filter(origin)? } verify { if !n.is_zero() { - assert!(!CallIndices::get().is_empty()); + assert!(!CallIndices::::get().is_empty()); } } @@ -120,7 +120,7 @@ benchmarks! { // Kill user account for worst case T::Currency::make_free_balance_be(&winner, 0u32.into()); // Assert that lotto is set up for winner - assert_eq!(TicketsCount::get(), 1); + assert_eq!(TicketsCount::::get(), 1); assert!(!Lottery::::pot().1.is_zero()); }: { // Generate `MaxGenerateRandom` numbers for worst case scenario @@ -132,7 +132,7 @@ benchmarks! { } verify { assert!(crate::Lottery::::get().is_none()); - assert_eq!(TicketsCount::get(), 0); + assert_eq!(TicketsCount::::get(), 0); assert_eq!(Lottery::::pot().1, 0u32.into()); assert!(!T::Currency::free_balance(&winner).is_zero()) } @@ -151,7 +151,7 @@ benchmarks! { // Kill user account for worst case T::Currency::make_free_balance_be(&winner, 0u32.into()); // Assert that lotto is set up for winner - assert_eq!(TicketsCount::get(), 1); + assert_eq!(TicketsCount::::get(), 1); assert!(!Lottery::::pot().1.is_zero()); }: { // Generate `MaxGenerateRandom` numbers for worst case scenario @@ -163,8 +163,8 @@ benchmarks! { } verify { assert!(crate::Lottery::::get().is_some()); - assert_eq!(LotteryIndex::get(), 2); - assert_eq!(TicketsCount::get(), 0); + 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()) } diff --git a/substrate/frame/lottery/src/lib.rs b/substrate/frame/lottery/src/lib.rs index a7782de029..5d6940c93b 100644 --- a/substrate/frame/lottery/src/lib.rs +++ b/substrate/frame/lottery/src/lib.rs @@ -60,58 +60,18 @@ use sp_runtime::{ traits::{AccountIdConversion, Saturating, Zero}, }; use frame_support::{ - Parameter, decl_module, decl_error, decl_event, decl_storage, ensure, RuntimeDebug, + ensure, PalletId, RuntimeDebug, dispatch::{Dispatchable, DispatchResult, GetDispatchInfo}, traits::{ - Currency, ReservableCurrency, Get, EnsureOrigin, ExistenceRequirement::KeepAlive, Randomness, + Currency, ReservableCurrency, Get, ExistenceRequirement::KeepAlive, Randomness, }, }; -use frame_support::{weights::Weight, PalletId}; -use frame_system::ensure_signed; use codec::{Encode, Decode}; pub use weights::WeightInfo; +pub use pallet::*; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -/// The module's config trait. -pub trait Config: frame_system::Config { - /// The Lottery's module id - type PalletId: Get; - - /// A dispatchable call. - type Call: Parameter + Dispatchable + GetDispatchInfo + From>; - - /// The currency trait. - type Currency: ReservableCurrency; - - /// Something that provides randomness in the runtime. - type Randomness: Randomness; - - /// The overarching event type. - type Event: From> + Into<::Event>; - - /// The manager origin. - type ManagerOrigin: EnsureOrigin; - - /// The max number of calls available in a single lottery. - type MaxCalls: Get; - - /// Used to determine if a call would be valid for purchasing a ticket. - /// - /// Be conscious of the implementation used here. We assume at worst that - /// a vector of `MaxCalls` indices are queried for any call validation. - /// You may need to provide a custom benchmark if this assumption is broken. - type ValidateCall: ValidateCall; - - /// Number of time we should try to generate a random number that has no modulo bias. - /// The larger this number, the more potential computation is used for picking the winner, - /// but also the more likely that the chosen winner is done fairly. - type MaxGenerateRandom: Get; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; -} - // 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. type CallIndex = (u8, u8); @@ -139,9 +99,9 @@ impl ValidateCall for () { fn validate_call(_: &::Call) -> bool { false } } -impl ValidateCall for Module { +impl ValidateCall for Pallet { fn validate_call(call: &::Call) -> bool { - let valid_calls = CallIndices::get(); + let valid_calls = CallIndices::::get(); let call_index = match Self::call_to_index(&call) { Ok(call_index) => call_index, Err(_) => return false, @@ -150,44 +110,74 @@ impl ValidateCall for Module { } } -decl_storage! { - trait Store for Module as Lottery { - LotteryIndex: u32; - /// The configuration for the current lottery. - Lottery: Option>>; - /// Users who have purchased a ticket. (Lottery Index, Tickets Purchased) - Participants: map hasher(twox_64_concat) T::AccountId => (u32, Vec); - /// Total number of tickets sold. - TicketsCount: u32; - /// Each ticket's owner. - /// - /// May have residual storage from previous lotteries. Use `TicketsCount` to see which ones - /// are actually valid ticket mappings. - Tickets: map hasher(twox_64_concat) u32 => Option; - /// The calls stored in this pallet to be used in an active lottery if configured - /// by `Config::ValidateCall`. - CallIndices: Vec; - } -} +#[frame_support::pallet] +pub mod pallet { + use frame_support::{Parameter, pallet_prelude::*, traits::EnsureOrigin, weights::Weight}; + use frame_system::{ensure_signed, pallet_prelude::*}; + use super::*; -decl_event!( - pub enum Event where - ::AccountId, - Balance = BalanceOf, - { + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + /// The pallet's config trait. + #[pallet::config] + pub trait Config: frame_system::Config { + /// The Lottery's pallet id + #[pallet::constant] + type PalletId: Get; + + /// A dispatchable call. + type Call: Parameter + Dispatchable + GetDispatchInfo + From>; + + /// The currency trait. + type Currency: ReservableCurrency; + + /// Something that provides randomness in the runtime. + type Randomness: Randomness; + + /// The overarching event type. + type Event: From> + IsType<::Event>; + + /// The manager origin. + type ManagerOrigin: EnsureOrigin; + + /// The max number of calls available in a single lottery. + #[pallet::constant] + type MaxCalls: Get; + + /// Used to determine if a call would be valid for purchasing a ticket. + /// + /// Be conscious of the implementation used here. We assume at worst that + /// a vector of `MaxCalls` indices are queried for any call validation. + /// You may need to provide a custom benchmark if this assumption is broken. + type ValidateCall: ValidateCall; + + /// Number of time we should try to generate a random number that has no modulo bias. + /// The larger this number, the more potential computation is used for picking the winner, + /// but also the more likely that the chosen winner is done fairly. + type MaxGenerateRandom: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + #[pallet::metadata(T::AccountId = "AccountId", BalanceOf = "Balance")] + pub enum Event { /// A lottery has been started! LotteryStarted, /// A new set of calls have been set! CallsUpdated, /// A winner has been chosen! - Winner(AccountId, Balance), + Winner(T::AccountId, BalanceOf), /// A ticket has been bought! - TicketBought(AccountId, CallIndex), + TicketBought(T::AccountId, CallIndex), } -); -decl_error! { - pub enum Error for Module { + #[pallet::error] + pub enum Error { /// A lottery has not been configured. NotConfigured, /// A lottery is already in progress. @@ -203,114 +193,41 @@ decl_error! { /// Failed to encode calls EncodingFailed, } -} -decl_module! { - pub struct Module for enum Call where origin: T::Origin, system = frame_system { - type Error = Error; + #[pallet::storage] + pub(crate) type LotteryIndex = StorageValue<_, u32, ValueQuery>; - const PalletId: PalletId = T::PalletId::get(); - const MaxCalls: u32 = T::MaxCalls::get() as u32; + /// The configuration for the current lottery. + #[pallet::storage] + pub(crate) type Lottery = StorageValue<_, LotteryConfig>>; - fn deposit_event() = default; + /// Users who have purchased a ticket. (Lottery Index, Tickets Purchased) + #[pallet::storage] + pub(crate) type Participants = StorageMap< + _, + Twox64Concat, T::AccountId, + (u32, Vec), + ValueQuery, + >; - /// Buy a ticket to enter the lottery. - /// - /// This extrinsic acts as a passthrough function for `call`. In all - /// situations where `call` alone would succeed, this extrinsic should - /// succeed. - /// - /// If `call` is successful, then we will attempt to purchase a ticket, - /// which may fail silently. To detect success of a ticket purchase, you - /// should listen for the `TicketBought` event. - /// - /// This extrinsic must be called by a signed origin. - #[weight = - T::WeightInfo::buy_ticket() - .saturating_add(call.get_dispatch_info().weight) - ] - fn buy_ticket(origin, call: Box<::Call>) { - let caller = ensure_signed(origin.clone())?; - call.clone().dispatch(origin).map_err(|e| e.error)?; + /// Total number of tickets sold. + #[pallet::storage] + pub(crate) type TicketsCount = StorageValue<_, u32, ValueQuery>; - let _ = Self::do_buy_ticket(&caller, &call); - } + /// Each ticket's owner. + /// + /// May have residual storage from previous lotteries. Use `TicketsCount` to see which ones + /// are actually valid ticket mappings. + #[pallet::storage] + pub(crate) type Tickets = StorageMap<_, Twox64Concat, u32, T::AccountId>; - /// Set calls in storage which can be used to purchase a lottery ticket. - /// - /// This function only matters if you use the `ValidateCall` implementation - /// provided by this pallet, which uses storage to determine the valid calls. - /// - /// This extrinsic must be called by the Manager origin. - #[weight = T::WeightInfo::set_calls(calls.len() as u32)] - fn set_calls(origin, calls: Vec<::Call>) { - T::ManagerOrigin::ensure_origin(origin)?; - ensure!(calls.len() <= T::MaxCalls::get(), Error::::TooManyCalls); - if calls.is_empty() { - CallIndices::kill(); - } else { - let indices = Self::calls_to_indices(&calls)?; - CallIndices::put(indices); - } - Self::deposit_event(RawEvent::CallsUpdated); - } - - /// Start a lottery using the provided configuration. - /// - /// This extrinsic must be called by the `ManagerOrigin`. - /// - /// Parameters: - /// - /// * `price`: The cost of a single ticket. - /// * `length`: How long the lottery should run for starting at the current block. - /// * `delay`: How long after the lottery end we should wait before picking a winner. - /// * `repeat`: If the lottery should repeat when completed. - #[weight = T::WeightInfo::start_lottery()] - fn start_lottery(origin, - price: BalanceOf, - length: T::BlockNumber, - delay: T::BlockNumber, - repeat: bool, - ) { - T::ManagerOrigin::ensure_origin(origin)?; - Lottery::::try_mutate(|lottery| -> DispatchResult { - ensure!(lottery.is_none(), Error::::InProgress); - let index = LotteryIndex::get(); - let new_index = index.checked_add(1).ok_or(ArithmeticError::Overflow)?; - let start = frame_system::Pallet::::block_number(); - // Use new_index to more easily track everything with the current state. - *lottery = Some(LotteryConfig { - price, - start, - length, - delay, - repeat, - }); - LotteryIndex::put(new_index); - Ok(()) - })?; - // Make sure pot exists. - let lottery_account = Self::account_id(); - if T::Currency::total_balance(&lottery_account).is_zero() { - T::Currency::deposit_creating(&lottery_account, T::Currency::minimum_balance()); - } - Self::deposit_event(RawEvent::LotteryStarted); - } - - /// If a lottery is repeating, you can use this to stop the repeat. - /// The lottery will continue to run to completion. - /// - /// This extrinsic must be called by the `ManagerOrigin`. - #[weight = T::WeightInfo::stop_repeat()] - fn stop_repeat(origin) { - T::ManagerOrigin::ensure_origin(origin)?; - Lottery::::mutate(|mut lottery| { - if let Some(config) = &mut lottery { - config.repeat = false - } - }); - } + /// The calls stored in this pallet to be used in an active lottery if configured + /// by `Config::ValidateCall`. + #[pallet::storage] + pub(crate) type CallIndices = StorageValue<_, Vec, ValueQuery>; + #[pallet::hooks] + impl Hooks> for Pallet { fn on_initialize(n: T::BlockNumber) -> Weight { Lottery::::mutate(|mut lottery| -> Weight { if let Some(config) = &mut lottery { @@ -319,7 +236,7 @@ decl_module! { .saturating_add(config.delay); if payout_block <= n { let (lottery_account, lottery_balance) = Self::pot(); - let ticket_count = TicketsCount::get(); + let ticket_count = TicketsCount::::get(); let winning_number = Self::choose_winner(ticket_count); let winner = Tickets::::get(winning_number).unwrap_or(lottery_account); @@ -327,13 +244,13 @@ decl_module! { let res = T::Currency::transfer(&Self::account_id(), &winner, lottery_balance, KeepAlive); debug_assert!(res.is_ok()); - Self::deposit_event(RawEvent::Winner(winner, lottery_balance)); + Self::deposit_event(Event::::Winner(winner, lottery_balance)); - TicketsCount::kill(); + TicketsCount::::kill(); if config.repeat { // If lottery should repeat, increment index by 1. - LotteryIndex::mutate(|index| *index = index.saturating_add(1)); + LotteryIndex::::mutate(|index| *index = index.saturating_add(1)); // Set a new start with the current block. config.start = n; return T::WeightInfo::on_initialize_repeat() @@ -351,9 +268,114 @@ decl_module! { }) } } + + #[pallet::call] + impl Pallet { + /// Buy a ticket to enter the lottery. + /// + /// This extrinsic acts as a passthrough function for `call`. In all + /// situations where `call` alone would succeed, this extrinsic should + /// succeed. + /// + /// If `call` is successful, then we will attempt to purchase a ticket, + /// which may fail silently. To detect success of a ticket purchase, you + /// should listen for the `TicketBought` event. + /// + /// This extrinsic must be called by a signed origin. + #[pallet::weight( + T::WeightInfo::buy_ticket() + .saturating_add(call.get_dispatch_info().weight) + )] + pub(crate) fn buy_ticket(origin: OriginFor, call: Box<::Call>) -> DispatchResult { + let caller = ensure_signed(origin.clone())?; + call.clone().dispatch(origin).map_err(|e| e.error)?; + + let _ = Self::do_buy_ticket(&caller, &call); + Ok(()) + } + + /// Set calls in storage which can be used to purchase a lottery ticket. + /// + /// This function only matters if you use the `ValidateCall` implementation + /// provided by this pallet, which uses storage to determine the valid calls. + /// + /// This extrinsic must be called by the Manager origin. + #[pallet::weight(T::WeightInfo::set_calls(calls.len() as u32))] + pub(crate) fn set_calls(origin: OriginFor, calls: Vec<::Call>) -> DispatchResult { + T::ManagerOrigin::ensure_origin(origin)?; + ensure!(calls.len() <= T::MaxCalls::get() as usize, Error::::TooManyCalls); + if calls.is_empty() { + CallIndices::::kill(); + } else { + let indices = Self::calls_to_indices(&calls)?; + CallIndices::::put(indices); + } + Self::deposit_event(Event::::CallsUpdated); + Ok(()) + } + + /// Start a lottery using the provided configuration. + /// + /// This extrinsic must be called by the `ManagerOrigin`. + /// + /// Parameters: + /// + /// * `price`: The cost of a single ticket. + /// * `length`: How long the lottery should run for starting at the current block. + /// * `delay`: How long after the lottery end we should wait before picking a winner. + /// * `repeat`: If the lottery should repeat when completed. + #[pallet::weight(T::WeightInfo::start_lottery())] + pub(crate) fn start_lottery( + origin: OriginFor, + price: BalanceOf, + length: T::BlockNumber, + delay: T::BlockNumber, + repeat: bool, + ) -> DispatchResult { + T::ManagerOrigin::ensure_origin(origin)?; + Lottery::::try_mutate(|lottery| -> DispatchResult { + ensure!(lottery.is_none(), Error::::InProgress); + let index = LotteryIndex::::get(); + let new_index = index.checked_add(1).ok_or(ArithmeticError::Overflow)?; + let start = frame_system::Pallet::::block_number(); + // Use new_index to more easily track everything with the current state. + *lottery = Some(LotteryConfig { + price, + start, + length, + delay, + repeat, + }); + LotteryIndex::::put(new_index); + Ok(()) + })?; + // Make sure pot exists. + let lottery_account = Self::account_id(); + if T::Currency::total_balance(&lottery_account).is_zero() { + T::Currency::deposit_creating(&lottery_account, T::Currency::minimum_balance()); + } + Self::deposit_event(Event::::LotteryStarted); + Ok(()) + } + + /// If a lottery is repeating, you can use this to stop the repeat. + /// The lottery will continue to run to completion. + /// + /// This extrinsic must be called by the `ManagerOrigin`. + #[pallet::weight(T::WeightInfo::stop_repeat())] + pub(crate) fn stop_repeat(origin: OriginFor) -> DispatchResult { + T::ManagerOrigin::ensure_origin(origin)?; + Lottery::::mutate(|mut lottery| { + if let Some(config) = &mut lottery { + config.repeat = false + } + }); + Ok(()) + } + } } -impl Module { +impl Pallet { /// The account ID of the lottery pot. /// /// This actually does computation. If you need to keep using it, then make sure you cache the @@ -397,11 +419,11 @@ impl Module { ensure!(block_number < config.start.saturating_add(config.length), Error::::AlreadyEnded); ensure!(T::ValidateCall::validate_call(call), Error::::InvalidCall); let call_index = Self::call_to_index(call)?; - let ticket_count = TicketsCount::get(); + let ticket_count = TicketsCount::::get(); let new_ticket_count = ticket_count.checked_add(1).ok_or(ArithmeticError::Overflow)?; // Try to update the participant status Participants::::try_mutate(&caller, |(lottery_index, participating_calls)| -> DispatchResult { - let index = LotteryIndex::get(); + let index = LotteryIndex::::get(); // If lottery index doesn't match, then reset participating calls and index. if *lottery_index != index { *participating_calls = Vec::new(); @@ -413,13 +435,13 @@ impl Module { // Check user has enough funds and send it to the Lottery account. T::Currency::transfer(caller, &Self::account_id(), config.price, KeepAlive)?; // Create a new ticket. - TicketsCount::put(new_ticket_count); + TicketsCount::::put(new_ticket_count); Tickets::::insert(ticket_count, caller.clone()); participating_calls.push(call_index); Ok(()) })?; - Self::deposit_event(RawEvent::TicketBought(caller.clone(), call_index)); + Self::deposit_event(Event::::TicketBought(caller.clone(), call_index)); Ok(()) } diff --git a/substrate/frame/lottery/src/mock.rs b/substrate/frame/lottery/src/mock.rs index ca372cc37e..b668fba859 100644 --- a/substrate/frame/lottery/src/mock.rs +++ b/substrate/frame/lottery/src/mock.rs @@ -97,7 +97,7 @@ impl pallet_balances::Config for Test { parameter_types! { pub const LotteryPalletId: PalletId = PalletId(*b"py/lotto"); - pub const MaxCalls: usize = 2; + pub const MaxCalls: u32 = 2; pub const MaxGenerateRandom: u32 = 10; } diff --git a/substrate/frame/lottery/src/tests.rs b/substrate/frame/lottery/src/tests.rs index 03c542d500..38994b2864 100644 --- a/substrate/frame/lottery/src/tests.rs +++ b/substrate/frame/lottery/src/tests.rs @@ -32,7 +32,7 @@ fn initial_state() { assert_eq!(Balances::free_balance(Lottery::account_id()), 0); assert!(crate::Lottery::::get().is_none()); assert_eq!(Participants::::get(&1), (0, vec![])); - assert_eq!(TicketsCount::get(), 0); + assert_eq!(TicketsCount::::get(), 0); assert!(Tickets::::get(0).is_none()); }); } @@ -61,7 +61,7 @@ fn basic_end_to_end_works() { // 20 from the transfer, 10 from buying a ticket assert_eq!(Balances::free_balance(&1), 100 - 20 - 10); assert_eq!(Participants::::get(&1).1.len(), 1); - assert_eq!(TicketsCount::get(), 1); + assert_eq!(TicketsCount::::get(), 1); // 1 owns the 0 ticket assert_eq!(Tickets::::get(0), Some(1)); @@ -69,21 +69,21 @@ fn basic_end_to_end_works() { assert_ok!(Lottery::buy_ticket(Origin::signed(2), call.clone())); assert_ok!(Lottery::buy_ticket(Origin::signed(3), call.clone())); assert_ok!(Lottery::buy_ticket(Origin::signed(4), call.clone())); - assert_eq!(TicketsCount::get(), 4); + assert_eq!(TicketsCount::::get(), 4); // Go to end run_to_block(20); assert_ok!(Lottery::buy_ticket(Origin::signed(5), call.clone())); // Ticket isn't bought - assert_eq!(TicketsCount::get(), 4); + assert_eq!(TicketsCount::::get(), 4); // Go to payout run_to_block(25); // User 1 wins assert_eq!(Balances::free_balance(&1), 70 + 40); // Lottery is reset and restarted - assert_eq!(TicketsCount::get(), 0); - assert_eq!(LotteryIndex::get(), 2); + assert_eq!(TicketsCount::::get(), 0); + assert_eq!(LotteryIndex::::get(), 2); assert_eq!( crate::Lottery::::get().unwrap(), LotteryConfig { @@ -100,7 +100,7 @@ fn basic_end_to_end_works() { #[test] fn set_calls_works() { new_test_ext().execute_with(|| { - assert!(!CallIndices::exists()); + assert!(!CallIndices::::exists()); let calls = vec![ Call::Balances(BalancesCall::force_transfer(0, 0, 0)), @@ -108,7 +108,7 @@ fn set_calls_works() { ]; assert_ok!(Lottery::set_calls(Origin::root(), calls)); - assert!(CallIndices::exists()); + assert!(CallIndices::::exists()); let too_many_calls = vec![ Call::Balances(BalancesCall::force_transfer(0, 0, 0)), @@ -123,7 +123,7 @@ fn set_calls_works() { // Clear calls assert_ok!(Lottery::set_calls(Origin::root(), vec![])); - assert!(CallIndices::get().is_empty()); + assert!(CallIndices::::get().is_empty()); }); } @@ -161,7 +161,7 @@ fn buy_ticket_works_as_simple_passthrough() { // This is just a basic transfer then assert_ok!(Lottery::buy_ticket(Origin::signed(1), call.clone())); assert_eq!(Balances::free_balance(&1), 100 - 20); - assert_eq!(TicketsCount::get(), 0); + assert_eq!(TicketsCount::::get(), 0); // Lottery is set up, but too expensive to enter, so `do_buy_ticket` fails. let calls = vec![ @@ -174,7 +174,7 @@ fn buy_ticket_works_as_simple_passthrough() { assert_ok!(Lottery::start_lottery(Origin::root(), 60, 10, 5, false)); assert_ok!(Lottery::buy_ticket(Origin::signed(1), call.clone())); assert_eq!(Balances::free_balance(&1), 100 - 20 - 20); - assert_eq!(TicketsCount::get(), 0); + assert_eq!(TicketsCount::::get(), 0); // If call would fail, the whole thing still fails the same let fail_call = Box::new(Call::Balances(BalancesCall::transfer(2, 1000))); @@ -192,11 +192,11 @@ fn buy_ticket_works_as_simple_passthrough() { // User can call other txs, but doesn't get a ticket let remark_call = Box::new(Call::System(SystemCall::remark(b"hello, world!".to_vec()))); assert_ok!(Lottery::buy_ticket(Origin::signed(2), remark_call)); - assert_eq!(TicketsCount::get(), 0); + assert_eq!(TicketsCount::::get(), 0); let successful_call = Box::new(Call::Balances(BalancesCall::transfer(2, 1))); assert_ok!(Lottery::buy_ticket(Origin::signed(2), successful_call)); - assert_eq!(TicketsCount::get(), 1); + assert_eq!(TicketsCount::::get(), 1); }); } @@ -214,7 +214,7 @@ fn buy_ticket_works() { // Can't buy ticket before start let call = Box::new(Call::Balances(BalancesCall::transfer(2, 1))); assert_ok!(Lottery::buy_ticket(Origin::signed(1), call.clone())); - assert_eq!(TicketsCount::get(), 0); + assert_eq!(TicketsCount::::get(), 0); // Start lottery assert_ok!(Lottery::start_lottery(Origin::root(), 1, 20, 5, false)); @@ -222,28 +222,28 @@ fn buy_ticket_works() { // Go to start, buy ticket for transfer run_to_block(5); assert_ok!(Lottery::buy_ticket(Origin::signed(1), call)); - assert_eq!(TicketsCount::get(), 1); + assert_eq!(TicketsCount::::get(), 1); // Can't buy another of the same ticket (even if call is slightly changed) let call = Box::new(Call::Balances(BalancesCall::transfer(3, 30))); assert_ok!(Lottery::buy_ticket(Origin::signed(1), call)); - assert_eq!(TicketsCount::get(), 1); + assert_eq!(TicketsCount::::get(), 1); // Buy ticket for remark let call = Box::new(Call::System(SystemCall::remark(b"hello, world!".to_vec()))); assert_ok!(Lottery::buy_ticket(Origin::signed(1), call.clone())); - assert_eq!(TicketsCount::get(), 2); + assert_eq!(TicketsCount::::get(), 2); // Go to end, can't buy tickets anymore run_to_block(20); assert_ok!(Lottery::buy_ticket(Origin::signed(2), call.clone())); - assert_eq!(TicketsCount::get(), 2); + assert_eq!(TicketsCount::::get(), 2); // Go to payout, can't buy tickets when there is no lottery open run_to_block(25); assert_ok!(Lottery::buy_ticket(Origin::signed(2), call.clone())); - assert_eq!(TicketsCount::get(), 0); - assert_eq!(LotteryIndex::get(), 1); + assert_eq!(TicketsCount::::get(), 0); + assert_eq!(LotteryIndex::::get(), 1); }); }