diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 05f75b14b9603..52eb5e42bd4da 100644 --- a/bin/node/runtime/src/lib.rs +++ b/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/frame/lottery/src/benchmarking.rs b/frame/lottery/src/benchmarking.rs index a2b8946ecc49a..8fe91088b84ea 100644 --- a/frame/lottery/src/benchmarking.rs +++ b/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/frame/lottery/src/lib.rs b/frame/lottery/src/lib.rs index a7782de029028..5d6940c93b3ea 100644 --- a/frame/lottery/src/lib.rs +++ b/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. +#[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::*; + + #[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. /// - /// 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; + /// 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; } -} -decl_event!( - pub enum Event where - ::AccountId, - Balance = BalanceOf, - { + #[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,17 +193,84 @@ 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>; + + /// The configuration for the current lottery. + #[pallet::storage] + pub(crate) type Lottery = StorageValue<_, LotteryConfig>>; + + /// Users who have purchased a ticket. (Lottery Index, Tickets Purchased) + #[pallet::storage] + pub(crate) type Participants = StorageMap< + _, + Twox64Concat, T::AccountId, + (u32, Vec), + ValueQuery, + >; + + /// Total number of tickets sold. + #[pallet::storage] + pub(crate) type TicketsCount = StorageValue<_, u32, ValueQuery>; + + /// 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>; + + /// 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 { + let payout_block = config.start + .saturating_add(config.length) + .saturating_add(config.delay); + if payout_block <= n { + let (lottery_account, lottery_balance) = Self::pot(); + let ticket_count = TicketsCount::::get(); - const PalletId: PalletId = T::PalletId::get(); - const MaxCalls: u32 = T::MaxCalls::get() as u32; + let winning_number = Self::choose_winner(ticket_count); + let winner = Tickets::::get(winning_number).unwrap_or(lottery_account); + // Not much we can do if this fails... + let res = T::Currency::transfer(&Self::account_id(), &winner, lottery_balance, KeepAlive); + debug_assert!(res.is_ok()); + + Self::deposit_event(Event::::Winner(winner, lottery_balance)); + + TicketsCount::::kill(); - fn deposit_event() = default; + if config.repeat { + // If lottery should repeat, increment index by 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() + } else { + // Else, kill the lottery storage. + *lottery = None; + return T::WeightInfo::on_initialize_end() + } + // We choose not need to kill Participants and Tickets to avoid a large number + // of writes at one time. Instead, data persists between lotteries, but is not used + // if it is not relevant. + } + } + return T::DbWeight::get().reads(1) + }) + } + } + #[pallet::call] + impl Pallet { /// Buy a ticket to enter the lottery. /// /// This extrinsic acts as a passthrough function for `call`. In all @@ -225,15 +282,16 @@ decl_module! { /// should listen for the `TicketBought` event. /// /// This extrinsic must be called by a signed origin. - #[weight = + #[pallet::weight( T::WeightInfo::buy_ticket() .saturating_add(call.get_dispatch_info().weight) - ] - fn buy_ticket(origin, call: Box<::Call>) { + )] + 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. @@ -242,17 +300,18 @@ decl_module! { /// 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>) { + #[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(), Error::::TooManyCalls); + ensure!(calls.len() <= T::MaxCalls::get() as usize, Error::::TooManyCalls); if calls.is_empty() { - CallIndices::kill(); + CallIndices::::kill(); } else { let indices = Self::calls_to_indices(&calls)?; - CallIndices::put(indices); + CallIndices::::put(indices); } - Self::deposit_event(RawEvent::CallsUpdated); + Self::deposit_event(Event::::CallsUpdated); + Ok(()) } /// Start a lottery using the provided configuration. @@ -265,17 +324,18 @@ decl_module! { /// * `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, + #[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 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. @@ -286,7 +346,7 @@ decl_module! { delay, repeat, }); - LotteryIndex::put(new_index); + LotteryIndex::::put(new_index); Ok(()) })?; // Make sure pot exists. @@ -294,66 +354,28 @@ decl_module! { if T::Currency::total_balance(&lottery_account).is_zero() { T::Currency::deposit_creating(&lottery_account, T::Currency::minimum_balance()); } - Self::deposit_event(RawEvent::LotteryStarted); + 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`. - #[weight = T::WeightInfo::stop_repeat()] - fn stop_repeat(origin) { + #[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 } }); - } - - fn on_initialize(n: T::BlockNumber) -> Weight { - Lottery::::mutate(|mut lottery| -> Weight { - if let Some(config) = &mut lottery { - let payout_block = config.start - .saturating_add(config.length) - .saturating_add(config.delay); - if payout_block <= n { - let (lottery_account, lottery_balance) = Self::pot(); - let ticket_count = TicketsCount::get(); - - let winning_number = Self::choose_winner(ticket_count); - let winner = Tickets::::get(winning_number).unwrap_or(lottery_account); - // Not much we can do if this fails... - 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)); - - TicketsCount::kill(); - - if config.repeat { - // If lottery should repeat, increment index by 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() - } else { - // Else, kill the lottery storage. - *lottery = None; - return T::WeightInfo::on_initialize_end() - } - // We choose not need to kill Participants and Tickets to avoid a large number - // of writes at one time. Instead, data persists between lotteries, but is not used - // if it is not relevant. - } - } - return T::DbWeight::get().reads(1) - }) + 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/frame/lottery/src/mock.rs b/frame/lottery/src/mock.rs index ca372cc37e24e..b668fba85951b 100644 --- a/frame/lottery/src/mock.rs +++ b/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/frame/lottery/src/tests.rs b/frame/lottery/src/tests.rs index 03c542d5000d1..38994b2864c62 100644 --- a/frame/lottery/src/tests.rs +++ b/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); }); }