fn select_and_update_validators(current_era: EraIndex) -> Option<Vec<T::AccountId>> {
        // I. Ensure minimum validator count
        let validator_count = <Validators<T>>::iter().count();
        let minimum_validator_count = Self::minimum_validator_count().max(1) as usize;

        if validator_count < minimum_validator_count {
            // There were not enough validators for even our minimal level of functionality.
            // This is bad🥺.
            // We should probably disable all functionality except for block production
            // and let the chain keep producing blocks until we can decide on a sufficiently
            // substantial set.
            // TODO: [Substrate]substrate#2494
            return None
        }

        let to_votes =
            |b: BalanceOf<T>| <T::CurrencyToVote as Convert<BalanceOf<T>, u64>>::convert(b) as u128;
        let to_balance = |e: u128| <T::CurrencyToVote as Convert<u128, BalanceOf<T>>>::convert(e);

        // II. Construct and fill in the V/G graph
        // TC is O(V + G*1), V means validator's number, G means guarantor's number
        // DB try is 2

        log!(
            debug,
            "💸 Construct and fill in the V/G graph for the era {:?}.",
            current_era,
        );
        let mut vg_graph: BTreeMap<T::AccountId, Vec<IndividualExposure<T::AccountId, BalanceOf<T>>>> =
            <Validators<T>>::iter().map(|(v_stash, _)|
                (v_stash, Vec::<IndividualExposure<T::AccountId, BalanceOf<T>>>::new())
            ).collect();
        for (guarantor, guarantee) in <Guarantors<T>>::iter() {
            let Guarantee { total: _, submitted_in, mut targets, suppressed: _ } = guarantee;

            // Filter out guarantee targets which were guaranteed before the most recent
            // slashing span.
            targets.retain(|ie| {
                <Self as Store>::SlashingSpans::get(&ie.who).map_or(
                    true,
                    |spans| submitted_in >= spans.last_nonzero_slash(),
                )
            });
            
            for target in targets {
                if let Some(g) = vg_graph.get_mut(&target.who) {
                     g.push(IndividualExposure {
                         who: guarantor.clone(),
                         value: target.value
                     });
                }
            }
        }

        // III. This part will cover
        // 1. Get `ErasStakers` with `stake_limit` and `vg_graph`
        // 2. Get `ErasValidatorPrefs`
        // 3. Get `total_valid_stakes`
        // 4. Fill in `validator_stakes`
        log!(
            debug,
            "💸 Build the erasStakers for the era {:?}.",
            current_era,
        );
        let mut eras_total_stakes: BalanceOf<T> = Zero::zero();
        let mut validators_stakes: Vec<(T::AccountId, u128)> = vec![];
        for (v_stash, voters) in vg_graph.iter() {
            let v_controller = Self::bonded(v_stash).unwrap();
            let v_ledger: StakingLedger<T::AccountId, BalanceOf<T>> =
                Self::ledger(&v_controller).unwrap();

            let stake_limit = Self::stake_limit(v_stash).unwrap_or(Zero::zero());

            // 0. Add to `validator_stakes` but skip adding to `eras_stakers` if stake limit goes 0
            if stake_limit == Zero::zero() {
                validators_stakes.push((v_stash.clone(), 0));
                continue;
            }

            // 1. Calculate the ratio
            let total_stakes = v_ledger.active.saturating_add(
                voters.iter().fold(
                    Zero::zero(),
                    |acc, ie| acc.saturating_add(ie.value)
                ));
            let valid_votes_ratio = Perbill::from_rational_approximation(stake_limit, total_stakes).min(Perbill::one());

            // 2. Calculate validator valid stake
            let own_stake = valid_votes_ratio * v_ledger.active;

            // 3. Construct exposure
            let mut new_exposure = Exposure {
                total: own_stake,
                own: own_stake,
                others: vec![]
            };
            for voter in voters {
                let g_valid_stake = valid_votes_ratio * voter.value;
                new_exposure.total = new_exposure.total.saturating_add(g_valid_stake);
                new_exposure.others.push(IndividualExposure {
                    who: voter.who.clone(),
                    value: g_valid_stake
                });
            }

            // 4. Update snapshots
            <ErasStakers<T>>::insert(&current_era, &v_stash, new_exposure.clone());
            let exposure_total = new_exposure.total;
            let mut exposure_clipped = new_exposure;
            let clipped_max_len = T::MaxGuarantorRewardedPerValidator::get() as usize;
            if exposure_clipped.others.len() > clipped_max_len {
                exposure_clipped.others.sort_by(|a, b| a.value.cmp(&b.value).reverse());
                exposure_clipped.others.truncate(clipped_max_len);
            }
            <ErasStakersClipped<T>>::insert(&current_era, &v_stash, exposure_clipped);

            <ErasValidatorPrefs<T>>::insert(&current_era, &v_stash, Self::validators(&v_stash).clone());
            if let Some(maybe_total_stakes) = eras_total_stakes.checked_add(&exposure_total) {
                eras_total_stakes = maybe_total_stakes;
            } else {
                eras_total_stakes = to_balance(u64::max_value() as u128);
            }

            // 5. Push validator stakes
            validators_stakes.push((v_stash.clone(), to_votes(exposure_total)))
        }

        // IV. TopDown Election Algorithm with Randomlization
        let to_elect = (Self::validator_count() as usize).min(validators_stakes.len());

        // If there's no validators, be as same as little validators
        if to_elect < minimum_validator_count {
            return None;
        }

        let elected_stashes= Self::do_election(validators_stakes, to_elect);
        log!(
            info,
            "💸 new validator set of size {:?} has been elected via for era {:?}",
            elected_stashes.len(),
            current_era,
        );

        // V. Update general staking storage
        // Set the new validator set in sessions.
        <CurrentElected<T>>::put(&elected_stashes);

        // Update slot stake.
        <ErasTotalStakes<T>>::insert(&current_era, eras_total_stakes);

        // In order to keep the property required by `n_session_ending`
        // that we must return the new validator set even if it's the same as the old,
        // as long as any underlying economic conditions have changed, we don't attempt
        // to do any optimization where we compare against the prior set.
        Some(elected_stashes)
    }
/// Select the new validator set at the end of the era.
///
/// Returns the a set of newly selected _stash_ IDs.
///
/// This should only be called at the end of an era.
Select the new validator set at the end of the era.
Returns the a set of newly selected _stash_ IDs.

This should only be called at the end of an era.
Select the new validator set at the end of the era . Returns the a set of newly selected _stash_ IDs . This should only be called at the end of an era .
fn select_and_update_validators(current_era: EraIndex) -> Option<Vec<T::AccountId>> {
        // I. Ensure minimum validator count
        let validator_count = <Validators<T>>::iter().count();
        let minimum_validator_count = Self::minimum_validator_count().max(1) as usize;
        if validator_count < minimum_validator_count {
            // There were not enough validators for even our minimal level of functionality.
            // This is bad🥺.
            // We should probably disable all functionality except for block production
            // and let the chain keep producing blocks until we can decide on a sufficiently
            // substantial set.
            // TODO: [Substrate]substrate#2494
            return None
        }
        let to_votes =
            |b: BalanceOf<T>| <T::CurrencyToVote as Convert<BalanceOf<T>, u64>>::convert(b) as u128;
        let to_balance = |e: u128| <T::CurrencyToVote as Convert<u128, BalanceOf<T>>>::convert(e);
        // II. Construct and fill in the V/G graph
        // TC is O(V + G*1), V means validator's number, G means guarantor's number
        // DB try is 2
        log!(
            debug,
            "💸 Construct and fill in the V/G graph for the era {:?}.",
            current_era,
        );
        let mut vg_graph: BTreeMap<T::AccountId, Vec<IndividualExposure<T::AccountId, BalanceOf<T>>>> =
            <Validators<T>>::iter().map(|(v_stash, _)|
                (v_stash, Vec::<IndividualExposure<T::AccountId, BalanceOf<T>>>::new())
            ).collect();
        for (guarantor, guarantee) in <Guarantors<T>>::iter() {
            let Guarantee { total: _, submitted_in, mut targets, suppressed: _ } = guarantee;
            // Filter out guarantee targets which were guaranteed before the most recent
            // slashing span.
            targets.retain(|ie| {
                <Self as Store>::SlashingSpans::get(&ie.who).map_or(
                    true,
                    |spans| submitted_in >= spans.last_nonzero_slash(),
                )
            });
            for target in targets {
                if let Some(g) = vg_graph.get_mut(&target.who) {
                     g.push(IndividualExposure {
                         who: guarantor.clone(),
                         value: target.value
                     });
                }
            }
        }
        // III. This part will cover
        // 1. Get `ErasStakers` with `stake_limit` and `vg_graph`
        // 2. Get `ErasValidatorPrefs`
        // 3. Get `total_valid_stakes`
        // 4. Fill in `validator_stakes`
        log!(
            debug,
            "💸 Build the erasStakers for the era {:?}.",
            current_era,
        );
        let mut eras_total_stakes: BalanceOf<T> = Zero::zero();
        let mut validators_stakes: Vec<(T::AccountId, u128)> = vec![];
        for (v_stash, voters) in vg_graph.iter() {
            let v_controller = Self::bonded(v_stash).unwrap();
            let v_ledger: StakingLedger<T::AccountId, BalanceOf<T>> =
                Self::ledger(&v_controller).unwrap();
            let stake_limit = Self::stake_limit(v_stash).unwrap_or(Zero::zero());
            // 0. Add to `validator_stakes` but skip adding to `eras_stakers` if stake limit goes 0
            if stake_limit == Zero::zero() {
                validators_stakes.push((v_stash.clone(), 0));
                continue;
            }
            // 1. Calculate the ratio
            let total_stakes = v_ledger.active.saturating_add(
                voters.iter().fold(
                    Zero::zero(),
                    |acc, ie| acc.saturating_add(ie.value)
                ));
            let valid_votes_ratio = Perbill::from_rational_approximation(stake_limit, total_stakes).min(Perbill::one());
            // 2. Calculate validator valid stake
            let own_stake = valid_votes_ratio * v_ledger.active;
            // 3. Construct exposure
            let mut new_exposure = Exposure {
                total: own_stake,
                own: own_stake,
                others: vec![]
            };
            for voter in voters {
                let g_valid_stake = valid_votes_ratio * voter.value;
                new_exposure.total = new_exposure.total.saturating_add(g_valid_stake);
                new_exposure.others.push(IndividualExposure {
                    who: voter.who.clone(),
                    value: g_valid_stake
                });
            }
            // 4. Update snapshots
            <ErasStakers<T>>::insert(&current_era, &v_stash, new_exposure.clone());
            let exposure_total = new_exposure.total;
            let mut exposure_clipped = new_exposure;
            let clipped_max_len = T::MaxGuarantorRewardedPerValidator::get() as usize;
            if exposure_clipped.others.len() > clipped_max_len {
                exposure_clipped.others.sort_by(|a, b| a.value.cmp(&b.value).reverse());
                exposure_clipped.others.truncate(clipped_max_len);
            }
            <ErasStakersClipped<T>>::insert(&current_era, &v_stash, exposure_clipped);
            <ErasValidatorPrefs<T>>::insert(&current_era, &v_stash, Self::validators(&v_stash).clone());
            if let Some(maybe_total_stakes) = eras_total_stakes.checked_add(&exposure_total) {
                eras_total_stakes = maybe_total_stakes;
            } else {
                eras_total_stakes = to_balance(u64::max_value() as u128);
            }
            // 5. Push validator stakes
            validators_stakes.push((v_stash.clone(), to_votes(exposure_total)))
        }
        // IV. TopDown Election Algorithm with Randomlization
        let to_elect = (Self::validator_count() as usize).min(validators_stakes.len());
        // If there's no validators, be as same as little validators
        if to_elect < minimum_validator_count {
            return None;
        }
        let elected_stashes= Self::do_election(validators_stakes, to_elect);
        log!(
            info,
            "💸 new validator set of size {:?} has been elected via for era {:?}",
            elected_stashes.len(),
            current_era,
        );
        // V. Update general staking storage
        // Set the new validator set in sessions.
        <CurrentElected<T>>::put(&elected_stashes);
        // Update slot stake.
        <ErasTotalStakes<T>>::insert(&current_era, eras_total_stakes);
        // In order to keep the property required by `n_session_ending`
        // that we must return the new validator set even if it's the same as the old,
        // as long as any underlying economic conditions have changed, we don't attempt
        // to do any optimization where we compare against the prior set.
        Some(elected_stashes)
    }
fn select_and_update_validators ( current_era : EraIndex ) -> Option < Vec < T :: AccountId > > { // I. Ensure minimum validator count let validator_count = < Validators < T > > :: iter ( ) . count ( ) ; let minimum_validator_count = Self :: minimum_validator_count ( ) . max ( 1 ) as usize ; if validator_count < minimum_validator_count { // There were not enough validators for even our minimal level of functionality. // This is bad🥺. // We should probably disable all functionality except for block production // and let the chain keep producing blocks until we can decide on a sufficiently // substantial set. // TODO: [Substrate]substrate#2494 return None } let to_votes = | b : BalanceOf < T > | < T :: CurrencyToVote as Convert < BalanceOf < T > , u64 > > :: convert ( b ) as u128 ; let to_balance = | e : u128 | < T :: CurrencyToVote as Convert < u128 , BalanceOf < T > > > :: convert ( e ) ; // II. Construct and fill in the V/G graph // TC is O(V + G*1), V means validator's number, G means guarantor's number // DB try is 2 log ! ( debug " current_era ) ; let mut vg_graph : BTreeMap < T :: AccountId , Vec < IndividualExposure < T :: AccountId , BalanceOf < T > > > > = < Validators < T > > :: iter ( ) . map ( | ( v_stash , _ ) | ( v_stash , Vec :: < IndividualExposure < T :: AccountId , BalanceOf < T > > > :: new ( ) ) ) . collect ( ) ; for ( guarantor , guarantee ) in < Guarantors < T > > :: iter ( ) { let Guarantee { total : _ , submitted_in , mut targets , suppressed : _ } = guarantee ; // Filter out guarantee targets which were guaranteed before the most recent // slashing span. targets . retain ( | ie | { < Self as Store > :: SlashingSpans :: get ( & ie . who ) . map_or ( true , | spans | submitted_in >= spans . last_nonzero_slash ( ) , ) } ) ; for target in targets { if let Some ( g ) = vg_graph . get_mut ( & target . who ) { g . push ( IndividualExposure { who : guarantor . clone ( ) , value : target . value } ) ; } } } // III. This part will cover // 1. Get `ErasStakers` with `stake_limit` and `vg_graph` // 2. Get `ErasValidatorPrefs` // 3. Get `total_valid_stakes` // 4. Fill in `validator_stakes` log ! ( debug " current_era ) ; let mut eras_total_stakes : BalanceOf < T > = Zero :: zero ( ) ; let mut validators_stakes : Vec < ( T :: AccountId , u128 ) > = vec ! [ ] ; for ( v_stash , voters ) in vg_graph . iter ( ) { let v_controller = Self :: bonded ( v_stash ) . unwrap ( ) ; let v_ledger : StakingLedger < T :: AccountId , BalanceOf < T > > = Self :: ledger ( & v_controller ) . unwrap ( ) ; let stake_limit = Self :: stake_limit ( v_stash ) . unwrap_or ( Zero :: zero ( ) ) ; // 0. Add to `validator_stakes` but skip adding to `eras_stakers` if stake limit goes 0 if stake_limit == Zero :: zero ( ) { validators_stakes . push ( ( v_stash . clone ( ) , 0 ) ) ; continue ; } // 1. Calculate the ratio let total_stakes = v_ledger . active . saturating_add ( voters . iter ( ) . fold ( Zero :: zero ( ) , | acc , ie | acc . saturating_add ( ie . value ) ) ) ; let valid_votes_ratio = Perbill :: from_rational_approximation ( stake_limit , total_stakes ) . min ( Perbill :: one ( ) ) ; // 2. Calculate validator valid stake let own_stake = valid_votes_ratio * v_ledger . active ; // 3. Construct exposure let mut new_exposure = Exposure { total : own_stake , own : own_stake , others : vec ! [ ] } ; for voter in voters { let g_valid_stake = valid_votes_ratio * voter . value ; new_exposure . total = new_exposure . total . saturating_add ( g_valid_stake ) ; new_exposure . others . push ( IndividualExposure { who : voter . who . clone ( ) , value : g_valid_stake } ) ; } // 4. Update snapshots < ErasStakers < T > > :: insert ( & current_era , & v_stash , new_exposure . clone ( ) ) ; let exposure_total = new_exposure . total ; let mut exposure_clipped = new_exposure ; let clipped_max_len = T :: MaxGuarantorRewardedPerValidator :: get ( ) as usize ; if exposure_clipped . others . len ( ) > clipped_max_len { exposure_clipped . others . sort_by ( | a , b | a . value . cmp ( & b . value ) . reverse ( ) ) ; exposure_clipped . others . truncate ( clipped_max_len ) ; } < ErasStakersClipped < T > > :: insert ( & current_era , & v_stash , exposure_clipped ) ; < ErasValidatorPrefs < T > > :: insert ( & current_era , & v_stash , Self :: validators ( & v_stash ) . clone ( ) ) ; if let Some ( maybe_total_stakes ) = eras_total_stakes . checked_add ( & exposure_total ) { eras_total_stakes = maybe_total_stakes ; } else { eras_total_stakes = to_balance ( u64 :: max_value ( ) as u128 ) ; } // 5. Push validator stakes validators_stakes . push ( ( v_stash . clone ( ) , to_votes ( exposure_total ) ) ) } // IV. TopDown Election Algorithm with Randomlization let to_elect = ( Self :: validator_count ( ) as usize ) . min ( validators_stakes . len ( ) ) ; // If there's no validators, be as same as little validators if to_elect < minimum_validator_count { return None ; } let elected_stashes = Self :: do_election ( validators_stakes , to_elect ) ; log ! ( info " elected_stashes len ( ) current_era ) ; // V. Update general staking storage // Set the new validator set in sessions. < CurrentElected < T > > :: put ( & elected_stashes ) ; // Update slot stake. < ErasTotalStakes < T > > :: insert ( & current_era , eras_total_stakes ) ; // In order to keep the property required by `n_session_ending` // that we must return the new validator set even if it's the same as the old, // as long as any underlying economic conditions have changed, we don't attempt // to do any optimization where we compare against the prior set. Some ( elected_stashes ) }
Select the new validator set at the end of the era.
Select the new validator set at the end of the era .
current_era
EraIndex