Recursive election provider as fallback (#9648)

* Recursive election provider as fallback

* minor fix

* Fix integrity tests

* Update frame/election-provider-multi-phase/src/lib.rs

Co-authored-by: Zeke Mostov <32168567+emostov@users.noreply.github.com>

* Fix everything

* fmt again

* Fix test

* Fix state machine warning

* Fix build

Co-authored-by: Zeke Mostov <32168567+emostov@users.noreply.github.com>
This commit is contained in:
Kian Paimani
2021-09-12 15:38:32 +01:00
committed by GitHub
parent c09d52ead7
commit 056fd9b8a8
12 changed files with 190 additions and 157 deletions
@@ -23,6 +23,8 @@ frame-system = { version = "4.0.0-dev", default-features = false, path = "../sys
[dev-dependencies]
sp-npos-elections = { version = "4.0.0-dev", path = "../../primitives/npos-elections" }
sp-runtime = { version = "4.0.0-dev", path = "../../primitives/runtime" }
sp-core = { version = "4.0.0-dev", path = "../../primitives/core" }
sp-io = { version = "4.0.0-dev", path = "../../primitives/io" }
[features]
default = ["std"]
@@ -18,6 +18,7 @@
//! An implementation of [`ElectionProvider`] that does an on-chain sequential phragmen.
use crate::{ElectionDataProvider, ElectionProvider};
use frame_support::{traits::Get, weights::DispatchClass};
use sp_npos_elections::*;
use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData, prelude::*};
@@ -53,11 +54,11 @@ pub struct OnChainSequentialPhragmen<T: Config>(PhantomData<T>);
/// Configuration trait of [`OnChainSequentialPhragmen`].
///
/// Note that this is similar to a pallet traits, but [`OnChainSequentialPhragmen`] is not a pallet.
pub trait Config {
/// The account identifier type.
type AccountId: IdentifierT;
/// The block number type.
type BlockNumber;
///
/// WARNING: the user of this pallet must ensure that the `Accuracy` type will work nicely with the
/// normalization operation done inside `seq_phragmen`. See
/// [`sp_npos_elections::assignment::try_normalize`] for more info.
pub trait Config: frame_system::Config {
/// The accuracy used to compute the election:
type Accuracy: PerThing128;
/// Something that provides the data for election.
@@ -87,6 +88,12 @@ impl<T: Config> ElectionProvider<T::AccountId, T::BlockNumber> for OnChainSequen
let staked = assignment_ratio_to_staked_normalized(assignments, &stake_of)?;
let weight = T::BlockWeights::get().max_block;
frame_system::Pallet::<T>::register_extra_weight_unchecked(
weight,
DispatchClass::Mandatory,
);
Ok(to_supports(&staked))
}
}
@@ -98,11 +105,49 @@ mod tests {
use sp_runtime::Perbill;
type AccountId = u64;
type BlockNumber = u32;
struct Runtime;
impl Config for Runtime {
type AccountId = AccountId;
type BlockNumber = u64;
pub type Header = sp_runtime::generic::Header<BlockNumber, sp_runtime::traits::BlakeTwo256>;
pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic<AccountId, (), (), ()>;
pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
frame_support::construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: frame_system::{Pallet, Call, Event<T>},
}
);
impl frame_system::Config for Runtime {
type SS58Prefix = ();
type BaseCallFilter = frame_support::traits::Everything;
type Origin = Origin;
type Index = AccountId;
type BlockNumber = BlockNumber;
type Call = Call;
type Hash = sp_core::H256;
type Hashing = sp_runtime::traits::BlakeTwo256;
type AccountId = AccountId;
type Lookup = sp_runtime::traits::IdentityLookup<Self::AccountId>;
type Header = sp_runtime::testing::Header;
type Event = ();
type BlockHashCount = ();
type DbWeight = ();
type BlockLength = ();
type BlockWeights = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type OnSetCode = ();
}
impl Config for Runtime {
type Accuracy = Perbill;
type DataProvider = mock_data_provider::DataProvider;
}
@@ -138,12 +183,14 @@ mod tests {
#[test]
fn onchain_seq_phragmen_works() {
assert_eq!(
OnChainPhragmen::elect().unwrap(),
vec![
(10, Support { total: 25, voters: vec![(1, 10), (3, 15)] }),
(30, Support { total: 35, voters: vec![(2, 20), (3, 15)] })
]
);
sp_io::TestExternalities::new_empty().execute_with(|| {
assert_eq!(
OnChainPhragmen::elect().unwrap(),
vec![
(10, Support { total: 25, voters: vec![(1, 10), (3, 15)] }),
(30, Support { total: 35, voters: vec![(2, 20), (3, 15)] })
]
);
})
}
}