Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ impl multi_block::Config for Runtime {
type TargetSnapshotPerBlock = TargetSnapshotPerBlock;
type AdminOrigin =
EitherOfDiverse<EnsureRoot<AccountId>, EnsureSignedBy<WestendStakingMiner, AccountId>>;
type ManagerOrigin =
EitherOfDiverse<EnsureRoot<AccountId>, EnsureSignedBy<WestendStakingMiner, AccountId>>;
type DataProvider = Staking;
type MinerConfig = Self;
type Verifier = MultiBlockElectionVerifier;
Expand Down
13 changes: 13 additions & 0 deletions prdoc/pr_10248.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
title: Fix origin check in EPMB's manage extrinsic
doc:
- audience: Runtime Dev
description: |-
Fix origin check in EPMB's manage extrinsic and:

- Break down `Admin` and `Manager` origins/extrinsics for easier configuration
- update the corresponding weights
crates:
- name: asset-hub-westend-runtime
bump: major
- name: pallet-election-provider-multi-block
bump: major
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
};
use frame_benchmarking::v2::*;
use frame_election_provider_support::{ElectionDataProvider, ElectionProvider};
use frame_support::pallet_prelude::*;
use frame_support::{assert_ok, pallet_prelude::*};

const SNAPSHOT_NOT_BIG_ENOUGH: &'static str = "Snapshot page is not full, you should run this \
benchmark with enough genesis stakers in staking (DataProvider) to fill a page of voters/targets \
Expand Down Expand Up @@ -253,10 +253,81 @@ mod benchmarks {
}

#[benchmark(pov_mode = Measured)]
fn manage() -> Result<(), BenchmarkError> {
// TODO
fn manage_fallback() -> Result<(), BenchmarkError> {
// heaviest case is emergency set.
#[cfg(test)]
crate::mock::ElectionStart::set(sp_runtime::traits::Bounded::max_value());
crate::Pallet::<T>::start().unwrap();

// roll to signed so the snapshot exists
Pallet::<T>::roll_until_before_matches(|| {
matches!(CurrentPhase::<T>::get(), Phase::Signed(_))
});

// set phase to emergency
CurrentPhase::<T>::set(Phase::Emergency);
let origin = T::ManagerOrigin::try_successful_origin()
.map_err(|_| -> BenchmarkError { "cannot create manager origin".into() })?;
#[block]
{
// fallback might decide to fail, that's okay..
let maybe_err = Pallet::<T>::manage(origin, crate::ManagerOperation::EmergencyFallback);
//.. but it cannot be bad origin.
assert!(maybe_err.is_ok() || maybe_err.unwrap_err() != DispatchError::BadOrigin.into());
}

Ok(())
}

#[benchmark(pov_mode = Measured)]
fn admin_set() -> Result<(), BenchmarkError> {
// heaviest case is emergency set.
#[cfg(test)]
crate::mock::ElectionStart::set(sp_runtime::traits::Bounded::max_value());
crate::Pallet::<T>::start().unwrap();

// mine a single page solution.
let solution = crate::Pallet::<T>::roll_to_signed_and_mine_solution(1);

// verify to get the support.
let (voter_pages, all_targets, desired_targets) =
crate::unsigned::miner::OffchainWorkerMiner::<T>::fetch_snapshot(T::Pages::get())
.map_err(|_| -> BenchmarkError { "fetch_snapshot".into() })?;
let supports = crate::unsigned::miner::BaseMiner::<T::MinerConfig>::check_feasibility(
&solution,
&voter_pages,
&all_targets,
desired_targets,
)
.map_err(|_| -> BenchmarkError { "check_feasibility".into() })?;

let single_support = supports
.first()
.cloned()
.ok_or_else(|| -> BenchmarkError { "no support".into() })?;

// set phase to emergency
CurrentPhase::<T>::set(Phase::Emergency);

// nothing is queued in verified just yet.
assert!(<T::Verifier as Verifier>::queued_score().is_none());

let origin = T::AdminOrigin::try_successful_origin()
.map_err(|_| -> BenchmarkError { "cannot create admin origin".into() })?;
#[block]
{}
{
assert_ok!(Pallet::<T>::admin(
origin,
crate::AdminOperation::EmergencySetSolution(
sp_std::boxed::Box::new(single_support),
solution.score,
),
));
}

// something is queued now.
assert!(<T::Verifier as Verifier>::queued_score().is_some());

Ok(())
}

Expand Down
Loading
Loading