Skip to content

Commit

Permalink
Add pallet-referenda-tracks
Browse files Browse the repository at this point in the history
feat(frame/referenda-tracks): add benchmarking tests
  • Loading branch information
pandres95 committed Mar 8, 2024
1 parent 09596fa commit b20a9cb
Show file tree
Hide file tree
Showing 11 changed files with 1,132 additions and 1 deletion.
20 changes: 20 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 @@ -343,6 +343,7 @@ members = [
"substrate/frame/ranked-collective",
"substrate/frame/recovery",
"substrate/frame/referenda",
"substrate/frame/referenda-tracks",
"substrate/frame/remark",
"substrate/frame/root-offences",
"substrate/frame/root-testing",
Expand Down
67 changes: 67 additions & 0 deletions substrate/frame/referenda-tracks/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
[package]
name = "pallet-referenda-tracks"
version = "4.0.0-dev"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
homepage = "https://substrate.io"
repository.workspace = true
description = "FRAME pallet to manage voting tracks in referenda"
readme = "README.md"

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

[dependencies]
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false }
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
serde = { version = "1.0.188", optional = true }
frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true }
frame-support = { path = "../support", default-features = false }
frame-system = { path = "../system", default-features = false }
sp-core = { path = "../../primitives/core", default-features = false }
sp-io = { path = "../../primitives/io", default-features = false }
sp-runtime = { path = "../../primitives/runtime", default-features = false }
sp-std = { path = "../../primitives/std", default-features = false }
pallet-referenda = { path = "../referenda", default-features = false }

[dev-dependencies]
sp-core = { path = "../../primitives/core", default-features = false}
pallet-scheduler = { path = "../scheduler" }
pallet-preimage = { path = "../preimage" }
pallet-balances = { path = "../balances" }

[features]
default = [ "std" ]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-scheduler/runtime-benchmarks",
"pallet-preimage/runtime-benchmarks",
"pallet-referenda/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
std = [
"codec/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"pallet-referenda/std",
"scale-info/std",
"serde",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-balances/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-preimage/try-runtime",
"pallet-referenda/try-runtime",
"sp-runtime/try-runtime",
]
18 changes: 18 additions & 0 deletions substrate/frame/referenda-tracks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Referenda Tracks Pallet

- [`Config`][Config]
- [`Call`][Call]

## Overview

Manage referenda voting tracks.

## Interface

### Dispatchable Functions

- `insert` - Insert a new referenda Track.
- `update` - Update the configuration of an existing referenda Track.
- `remove` - Remove an existing track

License: Apache-2.0
152 changes: 152 additions & 0 deletions substrate/frame/referenda-tracks/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// This file is part of Substrate.

// Copyright (C) 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.

//! Benchmarks for remarks pallet
#![cfg(feature = "runtime-benchmarks")]

use super::*;
use crate::{Event, OriginToTrackId, Pallet as ReferendaTracks, Tracks, TracksIds};
use frame_benchmarking::v2::*;
use frame_support::BoundedVec;
use frame_system::RawOrigin;
use pallet_referenda::{Curve, TrackInfo, TrackInfoOf};
use sp_runtime::{str_array as s, traits::AtLeast32Bit, Perbill};

type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
type BalanceOf<T, I> =
<<T as pallet_referenda::Config<I>>::Currency as frame_support::traits::Currency<
AccountIdOf<T>,
>>::Balance;

fn assert_last_event<T: Config<I>, I: 'static>(generic_event: <T as Config<I>>::RuntimeEvent) {
frame_system::Pallet::<T>::assert_last_event(generic_event.into());
}

fn track_info_of<T, I: 'static>() -> TrackInfoOf<T, I>
where
T: pallet_referenda::Config<I>,
BalanceOf<T, I>: AtLeast32Bit,
{
TrackInfo {
name: s("Test Track"),
max_deciding: 1,
decision_deposit: 0u32.into(),
prepare_period: 10u32.into(),
decision_period: 100u32.into(),
confirm_period: 10u32.into(),
min_enactment_period: 2u32.into(),
min_approval: Curve::LinearDecreasing {
length: Perbill::from_percent(100),
floor: Perbill::from_percent(50),
ceil: Perbill::from_percent(100),
},
min_support: Curve::LinearDecreasing {
length: Perbill::from_percent(100),
floor: Perbill::from_percent(0),
ceil: Perbill::from_percent(50),
},
}
}

fn max_tracks<T: Config<I>, I: 'static>() -> u32 {
T::MaxTracks::get()
}

fn max_track_id<T: Config<I>, I: 'static>() -> TrackIdOf<T, I> {
T::BenchmarkHelper::track_id(max_tracks::<T, I>())
}

fn prepare_tracks<T: Config<I>, I: 'static>(full: bool) {
let ids = (0..max_tracks::<T, I>() - 1)
.map(|x| T::BenchmarkHelper::track_id(x))
.collect::<Vec<TrackIdOf<T, I>>>();
let track = track_info_of::<T, I>();
let origin: PalletsOriginOf<T> = RawOrigin::Signed(whitelisted_caller()).into();

TracksIds::<T, I>::mutate(|tracks_ids| {
*tracks_ids = BoundedVec::truncate_from(ids.clone());
});
ids.iter().for_each(|id| {
Tracks::<T, I>::insert(id.clone(), track.clone());
OriginToTrackId::<T, I>::insert(origin.clone(), id.clone());
});

if full {
ReferendaTracks::<T, I>::insert(
RawOrigin::Root.into(),
max_track_id::<T, I>(),
track,
origin,
)
.expect("inserts last track");
}
}

#[instance_benchmarks]
mod benchmarks {
use super::*;

#[benchmark]
pub fn insert() {
// Setup code
prepare_tracks::<T, I>(false);

let id = max_track_id::<T, I>();
let track = track_info_of::<T, I>();
let origin: PalletsOriginOf<T> = RawOrigin::Signed(whitelisted_caller()).into();

#[extrinsic_call]
_(RawOrigin::Root, id, track, origin);

// Verification code
assert_last_event::<T, I>(Event::Created { id }.into());
}

#[benchmark]
pub fn update() {
// Setup code
prepare_tracks::<T, I>(true);

let id = max_track_id::<T, I>();
let caller = whitelisted_caller();
let track = track_info_of::<T, I>();

#[extrinsic_call]
_(RawOrigin::Signed(caller), id, track);

// Verification code
assert_last_event::<T, I>(Event::Updated { id }.into());
}

#[benchmark]
pub fn remove() {
// Setup code
prepare_tracks::<T, I>(true);

let id = max_track_id::<T, I>();
let origin = RawOrigin::Signed(whitelisted_caller()).into();

#[extrinsic_call]
_(RawOrigin::Root, id, origin);

// Verification code
assert_last_event::<T, I>(Event::Removed { id }.into());
}

impl_benchmark_test_suite!(ReferendaTracks, crate::mock::new_test_ext(None), crate::mock::Test);
}
31 changes: 31 additions & 0 deletions substrate/frame/referenda-tracks/src/impl_tracks_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use super::*;

impl<T: Config<I>, I> pallet_referenda::TracksInfo<BalanceOf<T, I>, BlockNumberFor<T>>
for Pallet<T, I>
{
type Id = T::TrackId;
type RuntimeOrigin = <T::RuntimeOrigin as OriginTrait>::PalletsOrigin;
type TracksIter = TracksIter<T, I>;

fn tracks() -> Self::TracksIter {
Tracks::<T, I>::iter().map(|(id, info)| Cow::Owned(Track { id, info }))
}
fn track_for(origin: &Self::RuntimeOrigin) -> Result<Self::Id, ()> {
OriginToTrackId::<T, I>::get(origin).ok_or(())
}
fn tracks_ids() -> Vec<Self::Id> {
TracksIds::<T, I>::get().into_inner()
}
fn info(id: Self::Id) -> Option<Cow<'static, TrackInfoOf<T, I>>> {
Tracks::<T, I>::get(id).map(Cow::Owned)
}
}

impl<T: Config<I>, I: 'static> Get<Vec<TrackOf<T, I>>> for crate::Pallet<T, I> {
fn get() -> Vec<TrackOf<T, I>> {
// expensive but it doesn't seem to be used anywhere
<Pallet<T, I> as pallet_referenda::TracksInfo<BalanceOf<T, I>, BlockNumberFor<T>>>::tracks()
.map(|t| t.into_owned())
.collect()
}
}
Loading

0 comments on commit b20a9cb

Please sign in to comment.