@@ -25,14 +25,11 @@ use codec::Decode;
2525use frame_benchmarking:: {
2626 account, impl_benchmark_test_suite, v2:: * , whitelisted_caller, BenchmarkError ,
2727} ;
28- use frame_support:: {
29- dispatch:: DispatchResult ,
30- traits:: { Currency , EnsureOrigin , Get , ReservableCurrency } ,
31- } ;
28+ use frame_support:: traits:: { Currency , EnsureOrigin , Get , ReservableCurrency } ;
3229use frame_system:: { pallet_prelude:: BlockNumberFor , EventRecord , RawOrigin } ;
3330use pallet_authorship:: EventHandler ;
3431use pallet_session:: { self as session, SessionManager } ;
35- use sp_std:: prelude:: * ;
32+ use sp_std:: { cmp , prelude:: * } ;
3633
3734pub type BalanceOf < T > =
3835 <<T as Config >:: Currency as Currency < <T as frame_system:: Config >:: AccountId > >:: Balance ;
@@ -94,7 +91,7 @@ fn register_candidates<T: Config>(count: u32) {
9491 assert ! ( <CandidacyBond <T >>:: get( ) > 0u32 . into( ) , "Bond cannot be zero!" ) ;
9592
9693 for who in candidates {
97- T :: Currency :: make_free_balance_be ( & who, <CandidacyBond < T > >:: get ( ) * 2u32 . into ( ) ) ;
94+ T :: Currency :: make_free_balance_be ( & who, <CandidacyBond < T > >:: get ( ) * 3u32 . into ( ) ) ;
9895 <CollatorSelection < T > >:: register_as_candidate ( RawOrigin :: Signed ( who) . into ( ) ) . unwrap ( ) ;
9996 }
10097}
@@ -107,8 +104,11 @@ fn min_candidates<T: Config>() -> u32 {
107104
108105fn min_invulnerables < T : Config > ( ) -> u32 {
109106 let min_collators = T :: MinEligibleCollators :: get ( ) ;
110- let candidates_length = <Candidates < T > >:: get ( ) . len ( ) ;
111- min_collators. saturating_sub ( candidates_length. try_into ( ) . unwrap ( ) )
107+ let candidates_length = <CandidateList < T > >:: decode_len ( )
108+ . unwrap_or_default ( )
109+ . try_into ( )
110+ . unwrap_or_default ( ) ;
111+ min_collators. saturating_sub ( candidates_length)
112112}
113113
114114#[ benchmarks( where T : pallet_authorship:: Config + session:: Config ) ]
@@ -160,22 +160,19 @@ mod benchmarks {
160160 . unwrap ( ) ;
161161 }
162162 // ... and register them.
163- for ( who, _) in candidates {
163+ for ( who, _) in candidates. iter ( ) {
164164 let deposit = <CandidacyBond < T > >:: get ( ) ;
165- T :: Currency :: make_free_balance_be ( & who, deposit * 1000_u32 . into ( ) ) ;
166- let incoming = CandidateInfo { who : who. clone ( ) , deposit } ;
167- <Candidates < T > >:: try_mutate ( |candidates| -> DispatchResult {
168- if !candidates. iter ( ) . any ( |candidate| candidate. who == who) {
169- T :: Currency :: reserve ( & who, deposit) ?;
170- candidates. try_push ( incoming) . expect ( "we've respected the bounded vec limit" ) ;
171- <LastAuthoredBlock < T > >:: insert (
172- who. clone ( ) ,
173- frame_system:: Pallet :: < T > :: block_number ( ) + T :: KickThreshold :: get ( ) ,
174- ) ;
175- }
176- Ok ( ( ) )
165+ T :: Currency :: make_free_balance_be ( who, deposit * 1000_u32 . into ( ) ) ;
166+ <CandidateList < T > >:: try_mutate ( |list| {
167+ list. try_push ( CandidateInfo { who : who. clone ( ) , deposit } ) . unwrap ( ) ;
168+ Ok :: < ( ) , BenchmarkError > ( ( ) )
177169 } )
178- . expect ( "only returns ok" ) ;
170+ . unwrap ( ) ;
171+ T :: Currency :: reserve ( who, deposit) ?;
172+ <LastAuthoredBlock < T > >:: insert (
173+ who. clone ( ) ,
174+ frame_system:: Pallet :: < T > :: block_number ( ) + T :: KickThreshold :: get ( ) ,
175+ ) ;
179176 }
180177
181178 // now we need to fill up invulnerables
@@ -226,10 +223,27 @@ mod benchmarks {
226223 }
227224
228225 #[ benchmark]
229- fn set_candidacy_bond ( ) -> Result < ( ) , BenchmarkError > {
230- let bond_amount: BalanceOf < T > = T :: Currency :: minimum_balance ( ) * 10u32 . into ( ) ;
226+ fn set_candidacy_bond (
227+ c : Linear < 0 , { T :: MaxCandidates :: get ( ) } > ,
228+ k : Linear < 0 , { T :: MaxCandidates :: get ( ) } > ,
229+ ) -> Result < ( ) , BenchmarkError > {
230+ let initial_bond_amount: BalanceOf < T > = T :: Currency :: minimum_balance ( ) * 2u32 . into ( ) ;
231+ <CandidacyBond < T > >:: put ( initial_bond_amount) ;
232+ register_validators :: < T > ( c) ;
233+ register_candidates :: < T > ( c) ;
234+ let kicked = cmp:: min ( k, c) ;
231235 let origin =
232236 T :: UpdateOrigin :: try_successful_origin ( ) . map_err ( |_| BenchmarkError :: Weightless ) ?;
237+ let bond_amount = if k > 0 {
238+ <CandidateList < T > >:: mutate ( |candidates| {
239+ for info in candidates. iter_mut ( ) . skip ( kicked as usize ) {
240+ info. deposit = T :: Currency :: minimum_balance ( ) * 3u32 . into ( ) ;
241+ }
242+ } ) ;
243+ T :: Currency :: minimum_balance ( ) * 3u32 . into ( )
244+ } else {
245+ T :: Currency :: minimum_balance ( )
246+ } ;
233247
234248 #[ extrinsic_call]
235249 _ ( origin as T :: RuntimeOrigin , bond_amount) ;
@@ -238,6 +252,35 @@ mod benchmarks {
238252 Ok ( ( ) )
239253 }
240254
255+ #[ benchmark]
256+ fn update_bond (
257+ c : Linear < { min_candidates :: < T > ( ) + 1 } , { T :: MaxCandidates :: get ( ) } > ,
258+ ) -> Result < ( ) , BenchmarkError > {
259+ <CandidacyBond < T > >:: put ( T :: Currency :: minimum_balance ( ) ) ;
260+ <DesiredCandidates < T > >:: put ( c) ;
261+
262+ register_validators :: < T > ( c) ;
263+ register_candidates :: < T > ( c) ;
264+
265+ let caller = <CandidateList < T > >:: get ( ) [ 0 ] . who . clone ( ) ;
266+ v2:: whitelist!( caller) ;
267+
268+ let bond_amount: BalanceOf < T > =
269+ T :: Currency :: minimum_balance ( ) + T :: Currency :: minimum_balance ( ) ;
270+
271+ #[ extrinsic_call]
272+ _ ( RawOrigin :: Signed ( caller. clone ( ) ) , bond_amount) ;
273+
274+ assert_last_event :: < T > (
275+ Event :: CandidateBondUpdated { account_id : caller, deposit : bond_amount } . into ( ) ,
276+ ) ;
277+ assert ! (
278+ <CandidateList <T >>:: get( ) . iter( ) . last( ) . unwrap( ) . deposit ==
279+ T :: Currency :: minimum_balance( ) * 2u32 . into( )
280+ ) ;
281+ Ok ( ( ) )
282+ }
283+
241284 // worse case is when we have all the max-candidate slots filled except one, and we fill that
242285 // one.
243286 #[ benchmark]
@@ -267,6 +310,36 @@ mod benchmarks {
267310 ) ;
268311 }
269312
313+ #[ benchmark]
314+ fn take_candidate_slot ( c : Linear < { min_candidates :: < T > ( ) + 1 } , { T :: MaxCandidates :: get ( ) } > ) {
315+ <CandidacyBond < T > >:: put ( T :: Currency :: minimum_balance ( ) ) ;
316+ <DesiredCandidates < T > >:: put ( 1 ) ;
317+
318+ register_validators :: < T > ( c) ;
319+ register_candidates :: < T > ( c) ;
320+
321+ let caller: T :: AccountId = whitelisted_caller ( ) ;
322+ let bond: BalanceOf < T > = T :: Currency :: minimum_balance ( ) * 10u32 . into ( ) ;
323+ T :: Currency :: make_free_balance_be ( & caller, bond) ;
324+
325+ <session:: Pallet < T > >:: set_keys (
326+ RawOrigin :: Signed ( caller. clone ( ) ) . into ( ) ,
327+ keys :: < T > ( c + 1 ) ,
328+ Vec :: new ( ) ,
329+ )
330+ . unwrap ( ) ;
331+
332+ let target = <CandidateList < T > >:: get ( ) . iter ( ) . last ( ) . unwrap ( ) . who . clone ( ) ;
333+
334+ #[ extrinsic_call]
335+ _ ( RawOrigin :: Signed ( caller. clone ( ) ) , bond / 2u32 . into ( ) , target. clone ( ) ) ;
336+
337+ assert_last_event :: < T > (
338+ Event :: CandidateReplaced { old : target, new : caller, deposit : bond / 2u32 . into ( ) }
339+ . into ( ) ,
340+ ) ;
341+ }
342+
270343 // worse case is the last candidate leaving.
271344 #[ benchmark]
272345 fn leave_intent ( c : Linear < { min_candidates :: < T > ( ) + 1 } , { T :: MaxCandidates :: get ( ) } > ) {
@@ -276,7 +349,7 @@ mod benchmarks {
276349 register_validators :: < T > ( c) ;
277350 register_candidates :: < T > ( c) ;
278351
279- let leaving = <Candidates < T > >:: get ( ) . last ( ) . unwrap ( ) . who . clone ( ) ;
352+ let leaving = <CandidateList < T > >:: get ( ) . iter ( ) . last ( ) . unwrap ( ) . who . clone ( ) ;
280353 v2:: whitelist!( leaving) ;
281354
282355 #[ extrinsic_call]
@@ -323,31 +396,37 @@ mod benchmarks {
323396
324397 let new_block: BlockNumberFor < T > = 1800u32 . into ( ) ;
325398 let zero_block: BlockNumberFor < T > = 0u32 . into ( ) ;
326- let candidates = <Candidates < T > >:: get ( ) ;
399+ let candidates: Vec < T :: AccountId > = <CandidateList < T > >:: get ( )
400+ . iter ( )
401+ . map ( |candidate_info| candidate_info. who . clone ( ) )
402+ . collect ( ) ;
327403
328404 let non_removals = c. saturating_sub ( r) ;
329405
330406 for i in 0 ..c {
331- <LastAuthoredBlock < T > >:: insert ( candidates[ i as usize ] . who . clone ( ) , zero_block) ;
407+ <LastAuthoredBlock < T > >:: insert ( candidates[ i as usize ] . clone ( ) , zero_block) ;
332408 }
333409
334410 if non_removals > 0 {
335411 for i in 0 ..non_removals {
336- <LastAuthoredBlock < T > >:: insert ( candidates[ i as usize ] . who . clone ( ) , new_block) ;
412+ <LastAuthoredBlock < T > >:: insert ( candidates[ i as usize ] . clone ( ) , new_block) ;
337413 }
338414 } else {
339415 for i in 0 ..c {
340- <LastAuthoredBlock < T > >:: insert ( candidates[ i as usize ] . who . clone ( ) , new_block) ;
416+ <LastAuthoredBlock < T > >:: insert ( candidates[ i as usize ] . clone ( ) , new_block) ;
341417 }
342418 }
343419
344420 let min_candidates = min_candidates :: < T > ( ) ;
345- let pre_length = <Candidates < T > >:: get ( ) . len ( ) ;
421+ let pre_length = <CandidateList < T > >:: decode_len ( ) . unwrap_or_default ( ) ;
346422
347423 frame_system:: Pallet :: < T > :: set_block_number ( new_block) ;
348424
349- assert ! ( <Candidates <T >>:: get( ) . len( ) == c as usize ) ;
350-
425+ let current_length: u32 = <CandidateList < T > >:: decode_len ( )
426+ . unwrap_or_default ( )
427+ . try_into ( )
428+ . unwrap_or_default ( ) ;
429+ assert ! ( c == current_length) ;
351430 #[ block]
352431 {
353432 <CollatorSelection < T > as SessionManager < _ > >:: new_session ( 0 ) ;
@@ -357,16 +436,20 @@ mod benchmarks {
357436 // candidates > removals and remaining candidates > min candidates
358437 // => remaining candidates should be shorter than before removal, i.e. some were
359438 // actually removed.
360- assert ! ( <Candidates <T >>:: get ( ) . len ( ) < pre_length) ;
439+ assert ! ( <CandidateList <T >>:: decode_len ( ) . unwrap_or_default ( ) < pre_length) ;
361440 } else if c > r && non_removals < min_candidates {
362441 // candidates > removals and remaining candidates would be less than min candidates
363442 // => remaining candidates should equal min candidates, i.e. some were removed up to
364443 // the minimum, but then any more were "forced" to stay in candidates.
365- assert ! ( <Candidates <T >>:: get( ) . len( ) == min_candidates as usize ) ;
444+ let current_length: u32 = <CandidateList < T > >:: decode_len ( )
445+ . unwrap_or_default ( )
446+ . try_into ( )
447+ . unwrap_or_default ( ) ;
448+ assert ! ( min_candidates == current_length) ;
366449 } else {
367450 // removals >= candidates, non removals must == 0
368451 // can't remove more than exist
369- assert ! ( <Candidates <T >>:: get ( ) . len ( ) == pre_length) ;
452+ assert ! ( <CandidateList <T >>:: decode_len ( ) . unwrap_or_default ( ) == pre_length) ;
370453 }
371454 }
372455
0 commit comments