33use super :: * ;
44use frame_benchmarking:: v2:: * ;
55use frame_support:: assert_ok;
6- use frame_support:: traits:: Currency ;
6+ use frame_support:: sp_runtime:: traits:: Saturating ;
7+ use frame_support:: traits:: { Currency , Get } ;
8+ use frame_system:: pallet_prelude:: BlockNumberFor ;
79use frame_system:: RawOrigin ;
810use primitives:: { Balance , EvmAddress } ;
911
@@ -49,7 +51,9 @@ mod benches {
4951 set_dummy_pool :: < T > ( ) ;
5052
5153 let caller: T :: AccountId = whitelisted_caller ( ) ;
52- let stake_amount: Balance = 100 * ONE ;
54+ let max: u32 = T :: MaxPendingUnstakes :: get ( ) ;
55+ let per_unstake: Balance = ONE ;
56+ let stake_amount: Balance = per_unstake. saturating_mul ( max as Balance ) . saturating_mul ( 2 ) ;
5357 fund :: < T > ( & caller, stake_amount. saturating_mul ( 10 ) ) ;
5458
5559 assert_ok ! ( Pallet :: <T >:: giga_stake(
@@ -58,18 +62,27 @@ mod benches {
5862 ) ) ;
5963
6064 // Worst case: payout > active → yield transferred from gigapot.
61- // Pre-fund the gigapot so the rate is > 1.
6265 let gigapot = Pallet :: < T > :: gigapot_account_id ( ) ;
6366 fund :: < T > ( & gigapot, stake_amount. saturating_mul ( 2 ) ) ;
6467
65- let stake = Stakes :: < T > :: get ( & caller) . expect ( "setup invariant" ) ;
66- let unstake_amount = stake. gigahdx ;
68+ // Pre-populate MaxPendingUnstakes - 1 positions across distinct blocks so
69+ // the measured call hits the admission cap and the cached-counter update
70+ // at the per-account upper bound.
71+ for _ in 0 ..max. saturating_sub ( 1 ) {
72+ assert_ok ! ( Pallet :: <T >:: giga_unstake(
73+ RawOrigin :: Signed ( caller. clone( ) ) . into( ) ,
74+ per_unstake,
75+ ) ) ;
76+ let next = frame_system:: Pallet :: < T > :: block_number ( ) . saturating_add ( 1u32 . into ( ) ) ;
77+ frame_system:: Pallet :: < T > :: set_block_number ( next) ;
78+ }
79+ let measured_amount = per_unstake;
6780
6881 #[ extrinsic_call]
69- giga_unstake ( RawOrigin :: Signed ( caller. clone ( ) ) , unstake_amount ) ;
82+ giga_unstake ( RawOrigin :: Signed ( caller. clone ( ) ) , measured_amount ) ;
7083
71- assert ! ( PendingUnstakes :: <T >:: get( & caller) . is_some ( ) ) ;
72- assert_eq ! ( Stakes :: < T > :: get ( & caller ) . map ( |s| s . gigahdx ) . unwrap_or_default ( ) , 0 ) ;
84+ let s = Stakes :: < T > :: get ( & caller) . expect ( "stake recorded" ) ;
85+ assert_eq ! ( s . unstaking_count as u32 , max ) ;
7386 }
7487
7588 #[ benchmark]
@@ -78,25 +91,37 @@ mod benches {
7891 set_dummy_pool :: < T > ( ) ;
7992
8093 let caller: T :: AccountId = whitelisted_caller ( ) ;
81- let stake_amount: Balance = 100 * ONE ;
94+ let max: u32 = T :: MaxPendingUnstakes :: get ( ) ;
95+ let per_unstake: Balance = ONE ;
96+ let stake_amount: Balance = per_unstake. saturating_mul ( max as Balance ) . saturating_mul ( 2 ) ;
8297 fund :: < T > ( & caller, stake_amount. saturating_mul ( 10 ) ) ;
8398
8499 assert_ok ! ( Pallet :: <T >:: giga_stake(
85100 RawOrigin :: Signed ( caller. clone( ) ) . into( ) ,
86101 stake_amount,
87102 ) ) ;
88- assert_ok ! ( Pallet :: <T >:: giga_unstake(
89- RawOrigin :: Signed ( caller. clone( ) ) . into( ) ,
90- stake_amount,
91- ) ) ;
92-
93- let position = PendingUnstakes :: < T > :: get ( & caller) . expect ( "position created" ) ;
94- frame_system:: Pallet :: < T > :: set_block_number ( position. expires_at ) ;
103+ let mut target_id: BlockNumberFor < T > = frame_system:: Pallet :: < T > :: block_number ( ) ;
104+ for i in 0 ..max {
105+ let id = frame_system:: Pallet :: < T > :: block_number ( ) ;
106+ assert_ok ! ( Pallet :: <T >:: giga_unstake(
107+ RawOrigin :: Signed ( caller. clone( ) ) . into( ) ,
108+ per_unstake,
109+ ) ) ;
110+ if i == 0 {
111+ target_id = id;
112+ }
113+ let next = id. saturating_add ( 1u32 . into ( ) ) ;
114+ frame_system:: Pallet :: < T > :: set_block_number ( next) ;
115+ }
116+
117+ let expires_at = target_id. saturating_add ( T :: CooldownPeriod :: get ( ) ) ;
118+ frame_system:: Pallet :: < T > :: set_block_number ( expires_at) ;
95119
96120 #[ extrinsic_call]
97- unlock ( RawOrigin :: Signed ( caller. clone ( ) ) ) ;
121+ unlock ( RawOrigin :: Signed ( caller. clone ( ) ) , target_id ) ;
98122
99- assert ! ( PendingUnstakes :: <T >:: get( & caller) . is_none( ) ) ;
123+ let s = Stakes :: < T > :: get ( & caller) . expect ( "stake remains" ) ;
124+ assert_eq ! ( s. unstaking_count as u32 , max - 1 ) ;
100125 }
101126
102127 #[ benchmark]
@@ -108,4 +133,46 @@ mod benches {
108133
109134 assert_eq ! ( GigaHdxPoolContract :: <T >:: get( ) , Some ( new_pool) ) ;
110135 }
136+
137+ #[ benchmark]
138+ fn cancel_unstake ( ) {
139+ assert_ok ! ( T :: BenchmarkHelper :: register_assets( ) ) ;
140+ set_dummy_pool :: < T > ( ) ;
141+
142+ let caller: T :: AccountId = whitelisted_caller ( ) ;
143+ let max: u32 = T :: MaxPendingUnstakes :: get ( ) ;
144+ let per_unstake: Balance = ONE ;
145+ let stake_amount: Balance = per_unstake. saturating_mul ( max as Balance ) . saturating_mul ( 2 ) ;
146+ fund :: < T > ( & caller, stake_amount. saturating_mul ( 10 ) ) ;
147+
148+ assert_ok ! ( Pallet :: <T >:: giga_stake(
149+ RawOrigin :: Signed ( caller. clone( ) ) . into( ) ,
150+ stake_amount,
151+ ) ) ;
152+
153+ // Worst case: yield was paid → cancel folds principal + yield back.
154+ let gigapot = Pallet :: < T > :: gigapot_account_id ( ) ;
155+ fund :: < T > ( & gigapot, stake_amount. saturating_mul ( 2 ) ) ;
156+
157+ let mut target_id: BlockNumberFor < T > = frame_system:: Pallet :: < T > :: block_number ( ) ;
158+ for i in 0 ..max {
159+ let id = frame_system:: Pallet :: < T > :: block_number ( ) ;
160+ assert_ok ! ( Pallet :: <T >:: giga_unstake(
161+ RawOrigin :: Signed ( caller. clone( ) ) . into( ) ,
162+ per_unstake,
163+ ) ) ;
164+ if i + 1 == max {
165+ target_id = id;
166+ }
167+ let next = id. saturating_add ( 1u32 . into ( ) ) ;
168+ frame_system:: Pallet :: < T > :: set_block_number ( next) ;
169+ }
170+
171+ #[ extrinsic_call]
172+ cancel_unstake ( RawOrigin :: Signed ( caller. clone ( ) ) , target_id) ;
173+
174+ let s = Stakes :: < T > :: get ( & caller) . expect ( "stake remains" ) ;
175+ assert_eq ! ( s. unstaking_count as u32 , max - 1 ) ;
176+ assert ! ( s. hdx > 0 ) ;
177+ }
111178}
0 commit comments