Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Participation Lottery Pallet #7221

Merged
40 commits merged into from
Jan 5, 2021
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
a1262a2
Basic design
shawntabrizi Sep 26, 2020
9380a57
Merge branch 'master' into shawntabrizi-lottery
shawntabrizi Nov 24, 2020
8ce5540
start adding tests
shawntabrizi Nov 25, 2020
fc12be9
finish tests
shawntabrizi Nov 25, 2020
d8f0598
clean up crates
shawntabrizi Nov 25, 2020
1289a8e
use call index for match
shawntabrizi Nov 25, 2020
82da7df
finish benchmarks
shawntabrizi Nov 25, 2020
14a5c44
add to runtime
shawntabrizi Nov 25, 2020
ed7c11e
Merge remote-tracking branch 'origin/master' into shawntabrizi-lottery
Nov 25, 2020
f67b119
fix
shawntabrizi Nov 25, 2020
48725b5
Merge branch 'shawntabrizi-lottery' of https://github.com/paritytech/…
shawntabrizi Nov 25, 2020
12a87b2
Merge remote-tracking branch 'origin/master' into shawntabrizi-lottery
Nov 25, 2020
90a3335
cargo run --release --features=runtime-benchmarks --manifest-path=bin…
Nov 25, 2020
844646b
more efficient storage
shawntabrizi Nov 25, 2020
23647d1
Merge remote-tracking branch 'origin/master' into shawntabrizi-lottery
Nov 25, 2020
a121177
cargo run --release --features=runtime-benchmarks --manifest-path=bin…
Nov 25, 2020
6b14824
Update lib.rs
shawntabrizi Nov 25, 2020
e9e0b5a
Update bin/node/runtime/src/lib.rs
shawntabrizi Nov 25, 2020
0ced83e
Merge branch 'master' into shawntabrizi-lottery
shawntabrizi Dec 1, 2020
eee7412
trait -> config
shawntabrizi Dec 1, 2020
47b1860
add repeating lottery
shawntabrizi Dec 1, 2020
05c97ef
new benchmarks
shawntabrizi Dec 1, 2020
c78726f
fix build
shawntabrizi Dec 1, 2020
5585006
move trait for warning
shawntabrizi Dec 1, 2020
5ded45d
feedback from @xlc
shawntabrizi Dec 1, 2020
9739b40
add stop_repeat
shawntabrizi Dec 1, 2020
ef67c0e
fix
shawntabrizi Dec 1, 2020
649cfa7
cargo run --release --features=runtime-benchmarks --manifest-path=bin…
Dec 1, 2020
d50bf84
Support static calls
shawntabrizi Dec 1, 2020
280afe6
Merge remote-tracking branch 'origin/master' into shawntabrizi-lottery
Dec 1, 2020
5460912
cargo run --release --features=runtime-benchmarks --manifest-path=bin…
Dec 1, 2020
171188a
Merge branch 'master' into shawntabrizi-lottery
shawntabrizi Dec 4, 2020
3164e13
Merge branch 'master' into shawntabrizi-lottery
shawntabrizi Dec 5, 2020
9707522
Merge branch 'master' into shawntabrizi-lottery
shawntabrizi Jan 1, 2021
c343e03
fix test
shawntabrizi Jan 1, 2021
8fc534c
add loop to mitigate modulo bias
shawntabrizi Jan 1, 2021
34e9c43
Update weights for worst case scenario loop
shawntabrizi Jan 1, 2021
e3c6a16
Initialize pot with ED
shawntabrizi Jan 5, 2021
7b4ee4a
Merge remote-tracking branch 'origin/master' into shawntabrizi-lottery
Jan 5, 2021
3de5a8b
cargo run --release --features=runtime-benchmarks --manifest-path=bin…
Jan 5, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ members = [
"frame/identity",
"frame/im-online",
"frame/indices",
"frame/lottery",
"frame/membership",
"frame/metadata",
"frame/multisig",
Expand Down
3 changes: 3 additions & 0 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pallet-grandpa = { version = "2.0.0", default-features = false, path = "../../..
pallet-im-online = { version = "2.0.0", default-features = false, path = "../../../frame/im-online" }
pallet-indices = { version = "2.0.0", default-features = false, path = "../../../frame/indices" }
pallet-identity = { version = "2.0.0", default-features = false, path = "../../../frame/identity" }
pallet-lottery = { version = "2.0.0", default-features = false, path = "../../../frame/lottery" }
pallet-membership = { version = "2.0.0", default-features = false, path = "../../../frame/membership" }
pallet-multisig = { version = "2.0.0", default-features = false, path = "../../../frame/multisig" }
pallet-offences = { version = "2.0.0", default-features = false, path = "../../../frame/offences" }
Expand Down Expand Up @@ -107,6 +108,7 @@ std = [
"pallet-im-online/std",
"pallet-indices/std",
"sp-inherents/std",
"pallet-lottery/std",
"pallet-membership/std",
"pallet-multisig/std",
"pallet-identity/std",
Expand Down Expand Up @@ -157,6 +159,7 @@ runtime-benchmarks = [
"pallet-identity/runtime-benchmarks",
"pallet-im-online/runtime-benchmarks",
"pallet-indices/runtime-benchmarks",
"pallet-lottery/runtime-benchmarks",
"pallet-multisig/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
"pallet-scheduler/runtime-benchmarks",
Expand Down
18 changes: 18 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,22 @@ impl pallet_vesting::Trait for Runtime {
type WeightInfo = pallet_vesting::weights::SubstrateWeight<Runtime>;
}

parameter_types! {
pub const LotteryModuleId: ModuleId = ModuleId(*b"py/lotto");
pub const MaxCalls: usize = 10;
}

impl pallet_lottery::Trait for Runtime {
type ModuleId = LotteryModuleId;
type Call = Call;
type Event = Event;
type Currency = Balances;
type Randomness = RandomnessCollectiveFlip;
type ManagerOrigin = EnsureRoot<AccountId>;
type MaxCalls = MaxCalls;
type WeightInfo = pallet_lottery::weights::SubstrateWeight<Runtime>;
}

construct_runtime!(
pub enum Runtime where
Block = Block,
Expand Down Expand Up @@ -929,6 +945,7 @@ construct_runtime!(
Scheduler: pallet_scheduler::{Module, Call, Storage, Event<T>},
Proxy: pallet_proxy::{Module, Call, Storage, Event<T>},
Multisig: pallet_multisig::{Module, Call, Storage, Event<T>},
Lottery: pallet_lottery::{Module, Call, Storage, Event<T>},
}
);

Expand Down Expand Up @@ -1205,6 +1222,7 @@ impl_runtime_apis! {
add_benchmark!(params, batches, pallet_identity, Identity);
add_benchmark!(params, batches, pallet_im_online, ImOnline);
add_benchmark!(params, batches, pallet_indices, Indices);
add_benchmark!(params, batches, pallet_lottery, Lottery);
add_benchmark!(params, batches, pallet_multisig, Multisig);
add_benchmark!(params, batches, pallet_offences, OffencesBench::<Runtime>);
add_benchmark!(params, batches, pallet_proxy, Proxy);
Expand Down
42 changes: 42 additions & 0 deletions frame/lottery/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[package]
name = "pallet-lottery"
version = "2.0.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
license = "Apache-2.0"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/substrate/"
description = "FRAME Participation Lottery Pallet"
readme = "README.md"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] }
sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" }
sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" }
frame-support = { version = "2.0.0", default-features = false, path = "../support" }
frame-system = { version = "2.0.0", default-features = false, path = "../system" }

frame-benchmarking = { version = "2.0.0", default-features = false, path = "../benchmarking", optional = true }

[dev-dependencies]
pallet-balances = { version = "2.0.0", path = "../balances" }
sp-core = { version = "2.0.0", path = "../../primitives/core" }
sp-io = { version = "2.0.0", path = "../../primitives/io" }

[features]
default = ["std"]
std = [
"codec/std",
"sp-std/std",
"frame-support/std",
"sp-runtime/std",
"frame-system/std",
]
runtime-benchmarks = [
"frame-benchmarking",
"frame-system/runtime-benchmarks",
"frame-support/runtime-benchmarks",
]
132 changes: 132 additions & 0 deletions frame/lottery/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// This file is part of Substrate.

// Copyright (C) 2020 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Lottery pallet benchmarking.

#![cfg(feature = "runtime-benchmarks")]

use super::*;

use frame_system::RawOrigin;
use frame_support::traits::{OnInitialize, UnfilteredDispatchable};
use frame_benchmarking::{benchmarks, account, whitelisted_caller};
use sp_runtime::traits::Bounded;

use crate::Module as Lottery;

// Set up and start a lottery
fn start_lottery<T: Trait>() -> Result<(), &'static str> {
let price = T::Currency::minimum_balance();
let start = 0u32.into();
let end = 10u32.into();
let payout = 15u32.into();
// Calls will be maximum length...
let mut calls = vec![
frame_system::Call::<T>::set_code(vec![]).into();
T::MaxCalls::get().saturating_sub(1)
];
// Last call will be the match for worst case scenario.
calls.push(frame_system::Call::<T>::remark(vec![]).into());
let origin = T::ManagerOrigin::successful_origin();
Lottery::<T>::setup_lottery(origin, price, start, end, payout, calls)?;
Ok(())
}

benchmarks! {
_ { }

setup_lottery {
let n in 0 .. T::MaxCalls::get() as u32;
let price = BalanceOf::<T>::max_value();
let start = 0u32.into();
let end = 10u32.into();
let payout = 15u32.into();
let calls = vec![frame_system::Call::<T>::remark(vec![]).into(); n as usize];

let call = Call::<T>::setup_lottery(price, start, end, payout, calls);
let origin = T::ManagerOrigin::successful_origin();
}: { call.dispatch_bypass_filter(origin)? }
verify {
assert!(crate::Lottery::<T>::get().is_some());
}

buy_ticket {
let caller = whitelisted_caller();
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
start_lottery::<T>()?;
// force user to have a long vec of calls participating
let set_code_index: CallIndex = Lottery::<T>::call_to_index(
&frame_system::Call::<T>::set_code(vec![]).into()
)?;
let already_called: (Index, Vec<CallIndex>) = (
LotteryIndex::get(),
vec![
set_code_index;
T::MaxCalls::get().saturating_sub(1)
],
);
Participants::<T>::insert(&caller, already_called);

let call = frame_system::Call::<T>::remark(vec![]);
}: _(RawOrigin::Signed(caller), Box::new(call.into()))
verify {
assert_eq!(TicketsCount::get(), 1);
}

on_initialize {
start_lottery::<T>()?;
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());
// Make sure lottery account has at least min balance too
let lottery_account = Lottery::<T>::account_id();
T::Currency::make_free_balance_be(&lottery_account, T::Currency::minimum_balance() * 10u32.into());
// Buy a ticket
let call = frame_system::Call::<T>::remark(vec![]);
Lottery::<T>::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());
// Assert that lotto is set up for winner
assert_eq!(TicketsCount::get(), 1);
assert!(!Lottery::<T>::pot().1.is_zero());
}: {
// Start lottery has block 15 configured for payout
Lottery::<T>::on_initialize(15u32.into());
}
verify {
assert!(crate::Lottery::<T>::get().is_none());
assert_eq!(TicketsCount::get(), 0);
assert_eq!(Lottery::<T>::pot().1, 0u32.into());
assert!(!T::Currency::free_balance(&winner).is_zero())
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::mock::{new_test_ext, Test};
use frame_support::assert_ok;

#[test]
fn test_benchmarks() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_setup_lottery::<Test>());
assert_ok!(test_benchmark_buy_ticket::<Test>());
assert_ok!(test_benchmark_on_initialize::<Test>());
});
}
}
Loading