Skip to content

Commit b7b75d7

Browse files
add multiple unstakes positions
1 parent 9c19cd9 commit b7b75d7

16 files changed

Lines changed: 1884 additions & 149 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/src/gigahdx.rs

Lines changed: 639 additions & 25 deletions
Large diffs are not rendered by default.

pallets/gigahdx/src/benchmarking.rs

Lines changed: 85 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
use super::*;
44
use frame_benchmarking::v2::*;
55
use 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;
79
use frame_system::RawOrigin;
810
use 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

Comments
 (0)