Skip to content

Commit a889247

Browse files
libreloisRomarQ
andauthored
Adds bounded, FIFO multi-request support for delegation scheduling in pallet-parachain-staking (#3550)
* implement multiple unbond requests * adapt benchmarks * end2end tests * cargo fmt * biome * fix rust tests compilation * fix migration warning * fmt * fix precompile tests * biome * test migration * biome * add MaxScheduledRequestsPerDelegator * benchmarks: pay_one_collator_reward_best: remove z param * fix rust tests * Optimization applied in get_rewardable_delegators Replaced the two-pass logic over scheduled_requests (one .any() for revokes, one loop to sum decreases) with a single-pass fold. * fix migration test * biome * multi-block migration * remove duplicate dep * review suggestion 1 * review suggestions 2 * review suggestions 3 * biome * fix migration * improve migration tests * rustfmt * migration test: ignore previous multi-block migrations * increase timeout for chopstick migration tests * biome * increase chopstick tests timeout * test migration: check state only after the multi-block migration ended * multi-migrations prevent transfer right after the upgrade * change test timeout * transfer need to wait multi-migrations * test upgrade chain: wait one block at a time * migration: migrate up to 8 collators per step * test migration: read less state for moonbeam * upgrade tests need long timeout to complete migrations * remove field delegator from ScheduledRequest type * comment why we can ignore try_push error * lazy-loading tests: multi-block migrations needs more time and blocks * fix staking benchmarks * fix precompile tests * fix proof size cost for precompile delegation_request_is_pending * improve benchmark check for pay_one_collator_reward_best * fix compilation * fix end2end tests that still rely on removed "delegator" field * fix lazy loading test * fix end2end tests that still rely on removed "delegator" field * skip upgrade test C01 on moonbeam * skip upgrade test C01 on moonbeam * Update pallets/parachain-staking/src/delegation_requests.rs Co-authored-by: Rodrigo Quelhas <[email protected]> * Update precompiles/parachain-staking/src/lib.rs Co-authored-by: Rodrigo Quelhas <[email protected]> * remove unused migrations * fix rust compilation --------- Co-authored-by: Rodrigo Quelhas <[email protected]>
1 parent cbc92dc commit a889247

File tree

46 files changed

+1487
-325
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1487
-325
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ jobs:
843843
uses: nick-fields/retry@v3
844844
with:
845845
max_attempts: 3
846-
timeout_minutes: 2
846+
timeout_minutes: 15
847847
retry_on: error
848848
command: |
849849
cd test

pallets/parachain-staking/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ scale-info = { workspace = true, features = [ "derive" ] }
1818
sp-consensus-slots = { workspace = true }
1919
sp-runtime = { workspace = true }
2020
sp-std = { workspace = true }
21+
sp-io = { workspace = true }
2122
substrate-fixed = { workspace = true }
2223

2324
# Nimbus
@@ -42,6 +43,7 @@ std = [
4243
"sp-consensus-slots/std",
4344
"sp-runtime/std",
4445
"sp-std/std",
46+
"sp-io/std",
4547
]
4648
runtime-benchmarks = [ "frame-benchmarking" ]
4749
try-runtime = [ "frame-support/try-runtime" ]

pallets/parachain-staking/src/benchmarks.rs

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -906,16 +906,14 @@ mod benchmarks {
906906
Pallet::<T>::delegator_state(&last_top_delegator).expect("delegator must exist");
907907
let current_round = Pallet::<T>::round().current;
908908
let delegator_delay = <<T as Config>::LeaveDelegatorsDelay>::get();
909+
910+
let scheduled = Pallet::<T>::delegation_scheduled_requests(&collator, &last_top_delegator);
909911
assert_eq!(
910-
Pallet::<T>::delegation_scheduled_requests(&collator)
911-
.iter()
912-
.find(|r| r.delegator == last_top_delegator)
913-
.cloned(),
914-
Some(ScheduledRequest {
915-
delegator: last_top_delegator,
912+
scheduled,
913+
sp_std::vec![ScheduledRequest {
916914
when_executable: current_round + delegator_delay,
917915
action: DelegationAction::Revoke(last_top_delegator_bond),
918-
}),
916+
}]
919917
);
920918
Ok(())
921919
}
@@ -1162,16 +1160,14 @@ mod benchmarks {
11621160
.expect("just request bonded less so exists");
11631161
let current_round = Pallet::<T>::round().current;
11641162
let delegator_delay = <<T as Config>::DelegationBondLessDelay>::get();
1163+
1164+
let scheduled = Pallet::<T>::delegation_scheduled_requests(&collator, &last_top_delegator);
11651165
assert_eq!(
1166-
Pallet::<T>::delegation_scheduled_requests(&collator)
1167-
.iter()
1168-
.find(|r| r.delegator == last_top_delegator)
1169-
.cloned(),
1170-
Some(ScheduledRequest {
1171-
delegator: last_top_delegator,
1166+
scheduled,
1167+
sp_std::vec![ScheduledRequest {
11721168
when_executable: current_round + delegator_delay,
11731169
action: DelegationAction::Decrease(bond_less),
1174-
}),
1170+
}]
11751171
);
11761172
Ok(())
11771173
}
@@ -1540,9 +1536,8 @@ mod benchmarks {
15401536
)?;
15411537
}
15421538

1543-
assert!(!Pallet::<T>::delegation_scheduled_requests(&collator)
1544-
.iter()
1545-
.any(|x| &x.delegator == &delegator));
1539+
let scheduled = Pallet::<T>::delegation_scheduled_requests(&collator, &delegator);
1540+
assert!(scheduled.is_empty());
15461541
Ok(())
15471542
}
15481543

@@ -1706,14 +1701,6 @@ mod benchmarks {
17061701
- 1
17071702
},
17081703
>,
1709-
// z is the number of scheduled requests per collator
1710-
z: Linear<
1711-
0,
1712-
{
1713-
T::MaxTopDelegationsPerCandidate::get() + T::MaxBottomDelegationsPerCandidate::get()
1714-
- 1
1715-
},
1716-
>,
17171704
) -> Result<(), BenchmarkError> {
17181705
use crate::{
17191706
AtStake, AwardedPts, BondWithAutoCompound, CollatorSnapshot, DelayedPayout,
@@ -1753,13 +1740,6 @@ mod benchmarks {
17531740
},
17541741
)?;
17551742
col_del_count += 1u32;
1756-
if i < z {
1757-
Pallet::<T>::schedule_delegator_bond_less(
1758-
RawOrigin::Signed(delegator.clone()).into(),
1759-
prime_candidate.clone(),
1760-
5u32.into(),
1761-
)?;
1762-
}
17631743

17641744
delegations.push(BondWithAutoCompound {
17651745
owner: delegator.clone(),
@@ -1793,6 +1773,10 @@ mod benchmarks {
17931773
<Points<T>>::insert(round_for_payout, 100);
17941774
<AwardedPts<T>>::insert(round_for_payout, &prime_candidate, 20);
17951775

1776+
// Measure the cost of minting and compounding rewards for `x` delegations,
1777+
// of which `y` have non-zero auto-compound. This mirrors the inner loop of
1778+
// `pay_one_collator_reward` where rewards are distributed to delegators and
1779+
// optionally compounded back into their stake.
17961780
#[block]
17971781
{
17981782
for BondWithAutoCompound {
@@ -1801,7 +1785,7 @@ mod benchmarks {
18011785
..
18021786
} in &delegations
18031787
{
1804-
<Pallet<T>>::mint_and_compound(
1788+
Pallet::<T>::mint_and_compound(
18051789
100u32.into(),
18061790
auto_compound.clone(),
18071791
prime_candidate.clone(),
@@ -1810,12 +1794,17 @@ mod benchmarks {
18101794
}
18111795
}
18121796

1797+
// All delegators should see their free balance increase as a result of
1798+
// `mint_and_compound`, regardless of their auto-compound percentage
1799+
// (auto-compound only controls how much of the reward is re-bonded,
1800+
// not whether the reward is minted in the first place).
18131801
for BondWithAutoCompound { owner, .. } in &delegations {
18141802
assert!(
1815-
<T::Currency as Inspect<T::AccountId>>::balance(&owner) > initial_delegator_balance,
1816-
"delegator should have been paid in pay_one_collator_reward"
1803+
<T::Currency as Inspect<T::AccountId>>::balance(owner) > initial_delegator_balance,
1804+
"delegator should have been paid in pay_one_collator_reward_best",
18171805
);
18181806
}
1807+
18191808
Ok(())
18201809
}
18211810

0 commit comments

Comments
 (0)