diff --git a/substrate/frame/election-provider-multi-phase/src/lib.rs b/substrate/frame/election-provider-multi-phase/src/lib.rs index bf511ece1c52..8676be438300 100644 --- a/substrate/frame/election-provider-multi-phase/src/lib.rs +++ b/substrate/frame/election-provider-multi-phase/src/lib.rs @@ -248,7 +248,7 @@ use codec::{Decode, Encode}; use frame_election_provider_support::{ bounds::{CountBound, ElectionBounds, ElectionBoundsBuilder, SizeBound}, BoundedSupports, BoundedSupportsOf, DataProviderBounds, ElectionDataProvider, ElectionProvider, - InstantElectionProvider, NposSolution, PageIndex, TryIntoBoundedSupports, + InstantElectionProvider, NposSolution, PageIndex, }; use frame_support::{ dispatch::DispatchClass, @@ -1007,7 +1007,7 @@ pub mod pallet { // bound supports with T::MaxWinners. let supports: BoundedSupportsOf> = - supports.try_into_bounded_supports().map_err(|_| Error::::TooManyWinners)?; + supports.try_into().map_err(|_| Error::::TooManyWinners)?; // Note: we don't `rotate_round` at this point; the next call to // `ElectionProvider::elect` will succeed and take care of that. @@ -2534,7 +2534,7 @@ mod tests { (30, Support { total: 40, voters: vec![(2, 5), (4, 5), (30, 30)] }), (40, Support { total: 60, voters: vec![(2, 5), (3, 10), (4, 5), (40, 40)] }), ] - .try_into_bounded_supports() + .try_into() .unwrap(); assert_eq!(supports, expected_supports); diff --git a/substrate/frame/election-provider-multi-phase/src/unsigned.rs b/substrate/frame/election-provider-multi-phase/src/unsigned.rs index 00b41bbb2558..90b12343aaeb 100644 --- a/substrate/frame/election-provider-multi-phase/src/unsigned.rs +++ b/substrate/frame/election-provider-multi-phase/src/unsigned.rs @@ -24,9 +24,7 @@ use crate::{ }; use alloc::{boxed::Box, vec::Vec}; use codec::Encode; -use frame_election_provider_support::{ - NposSolution, NposSolver, PerThing128, TryIntoBoundedSupports, VoteWeight, -}; +use frame_election_provider_support::{NposSolution, NposSolver, PerThing128, VoteWeight}; use frame_support::{ dispatch::DispatchResult, ensure, @@ -823,7 +821,7 @@ impl Miner { // Size of winners in miner solution is equal to `desired_targets` <= `MaxWinners`. let supports = supports - .try_into_bounded_supports() + .try_into() .defensive_map_err(|_| FeasibilityError::BoundedConversionFailed)?; Ok(ReadySolution { supports, compute, score }) diff --git a/substrate/frame/election-provider-support/src/lib.rs b/substrate/frame/election-provider-support/src/lib.rs index d1990e4b52fd..49bd533cc8c3 100644 --- a/substrate/frame/election-provider-support/src/lib.rs +++ b/substrate/frame/election-provider-support/src/lib.rs @@ -849,33 +849,30 @@ impl, BInner: Get> IntoIterator } } -/// An extension trait to convert from [`sp_npos_elections::Supports`] into -/// [`BoundedSupports`]. -pub trait TryIntoBoundedSupports, BInner: Get> { - /// Perform the conversion. - fn try_into_bounded_supports(self) -> Result, ()>; -} - -impl, BInner: Get> - TryIntoBoundedSupports for sp_npos_elections::Supports +impl, BInner: Get> TryFrom> + for BoundedSupports { - fn try_into_bounded_supports(self) -> Result, ()> { + type Error = crate::Error; + + fn try_from(supports: sp_npos_elections::Supports) -> Result { // optimization note: pre-allocate outer bounded vec. let mut outer_bounded_supports = BoundedVec::< (AccountId, BoundedSupport), BOuter, >::with_bounded_capacity( - self.len().min(BOuter::get() as usize) + supports.len().min(BOuter::get() as usize) ); // optimization note: avoid intermediate allocations. - self.into_iter() + supports + .into_iter() .map(|(account, support)| (account, support.try_into().map_err(|_| ()))) .try_for_each(|(account, maybe_bounded_supports)| { outer_bounded_supports .try_push((account, maybe_bounded_supports?)) .map_err(|_| ()) - })?; + }) + .map_err(|_| crate::Error::BoundsExceeded)?; Ok(outer_bounded_supports.into()) } diff --git a/substrate/frame/election-provider-support/src/onchain.rs b/substrate/frame/election-provider-support/src/onchain.rs index be59450ce148..379dccee2ce6 100644 --- a/substrate/frame/election-provider-support/src/onchain.rs +++ b/substrate/frame/election-provider-support/src/onchain.rs @@ -22,7 +22,7 @@ use crate::{ bounds::{DataProviderBounds, ElectionBounds, ElectionBoundsBuilder}, BoundedSupportsOf, Debug, ElectionDataProvider, ElectionProvider, InstantElectionProvider, - NposSolver, PageIndex, TryIntoBoundedSupports, WeightInfo, Zero, + NposSolver, PageIndex, WeightInfo, Zero, }; use alloc::collections::btree_map::BTreeMap; use core::marker::PhantomData; @@ -147,9 +147,8 @@ impl OnChainExecution { // defensive: Since npos solver returns a result always bounded by `desired_targets`, this // is never expected to happen as long as npos solver does what is expected for it to do. - let supports: BoundedSupportsOf = to_supports(&staked) - .try_into_bounded_supports() - .map_err(|_| Error::TooManyWinners)?; + let supports: BoundedSupportsOf = + to_supports(&staked).try_into().map_err(|_| Error::TooManyWinners)?; Ok(supports) } @@ -321,7 +320,7 @@ mod tests { ), (30, Support { total: 35, voters: vec![(2, 20), (3, 15)] }), ] - .try_into_bounded_supports() + .try_into() .unwrap(); assert_eq!( @@ -357,7 +356,7 @@ mod tests { ), (30, Support { total: 35, voters: vec![(2, 20), (3, 15)] }) ] - .try_into_bounded_supports() + .try_into() .unwrap() ); }) diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 12a418138785..79491ad5434c 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -21,7 +21,7 @@ use crate::{self as pallet_staking, *}; use frame_election_provider_support::{ bounds::{ElectionBounds, ElectionBoundsBuilder}, onchain, BoundedSupports, BoundedSupportsOf, ElectionProvider, PageIndex, SequentialPhragmen, - Support, TryIntoBoundedSupports, VoteWeight, + Support, VoteWeight, }; use frame_support::{ assert_ok, derive_impl, ord_parameter_types, parameter_types, @@ -1023,5 +1023,5 @@ pub(crate) fn to_bounded_supports( <::ElectionProvider as ElectionProvider>::MaxWinnersPerPage, <::ElectionProvider as ElectionProvider>::MaxBackersPerWinner, > { - supports.try_into_bounded_supports().unwrap() + supports.try_into().unwrap() } diff --git a/substrate/primitives/npos-elections/src/lib.rs b/substrate/primitives/npos-elections/src/lib.rs index 9a9d33aa8e20..96af46e30f63 100644 --- a/substrate/primitives/npos-elections/src/lib.rs +++ b/substrate/primitives/npos-elections/src/lib.rs @@ -127,6 +127,8 @@ pub enum Error { InvalidSupportEdge, /// The number of voters is bigger than the `MaxVoters` bound. TooManyVoters, + /// Some bounds were exceeded when converting election types. + BoundsExceeded, } /// A type which is used in the API of this crate as a numeric weight of a vote, most often the