Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dApp Staking v3 - Shibuya integration #1109

Merged
merged 35 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
68e4153
dApp staking v3 - Shibuya integration
Dinonard Dec 18, 2023
539e700
Init
Dinonard Dec 18, 2023
f8923e5
Fix build
Dinonard Dec 18, 2023
1a0954d
Fix find/replace doc mess
Dinonard Dec 18, 2023
3954524
Migration & disable
Dinonard Dec 18, 2023
efba128
More integration
Dinonard Dec 18, 2023
801e272
Progress
Dinonard Dec 19, 2023
acc9bcf
Adjusted integration
Dinonard Dec 19, 2023
7a6b875
Finished integration
Dinonard Dec 19, 2023
df1f936
Additional modifications & cleanup
Dinonard Dec 19, 2023
5574e0a
Move comment
Dinonard Dec 19, 2023
69d2f4d
Fixes
Dinonard Dec 19, 2023
779ee1f
Shibuya integration tests fix & proxy
Dinonard Dec 19, 2023
43d6421
Renaming
Dinonard Dec 19, 2023
b4895b2
Integration test fixes & legacy support
Dinonard Dec 19, 2023
c73e49d
Adjust for benchmarks
Dinonard Dec 19, 2023
b105db0
Merge remote-tracking branch 'origin/feat/dapp-staking-v3' into feat/…
Dinonard Dec 19, 2023
157d20a
Remove chain-extension, small updates
Dinonard Dec 19, 2023
0868b3d
fixes
Dinonard Dec 19, 2023
a3d51a7
Partial weights
Dinonard Dec 19, 2023
dce2a31
Minor changes
Dinonard Dec 19, 2023
d380ff6
Benchmark fixes
Dinonard Dec 19, 2023
c6cef61
dApp staking weights
Dinonard Dec 20, 2023
0bd6338
Weights, deps
Dinonard Dec 20, 2023
b853cc9
Remove redundant storage item
Dinonard Dec 20, 2023
1992221
Inflation params, resolve TODOs
Dinonard Dec 20, 2023
72f549b
Optimize lengthy benchmark
Dinonard Dec 20, 2023
76e681f
Integration test
Dinonard Dec 20, 2023
9b3b03d
Sort out more TODOs
Dinonard Dec 20, 2023
447e19f
Benchmark optimization
Dinonard Dec 20, 2023
367535c
Fix seed
Dinonard Dec 20, 2023
55c2dd5
Remove spec version bump
Dinonard Dec 20, 2023
a45e52d
Fix integration test
Dinonard Dec 20, 2023
62254ef
Merge remote-tracking branch 'origin/feat/dapp-staking-v3' into feat/…
Dinonard Dec 20, 2023
81fb86d
Weights update
Dinonard Dec 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 94 additions & 45 deletions pallets/dapp-staking-v3/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ use ::assert_matches::assert_matches;
mod utils;
use utils::*;

// A lot of benchmarks which require many blocks, eras or periods to pass have been optimized to utilize
// `force` approach, which skips the required amount of blocks that need to be produced in order to advance.
//
// Without this optimization, benchmarks can take hours to execute for production runtimes.

#[benchmarks]
mod benchmarks {
use super::*;
Expand Down Expand Up @@ -220,7 +225,7 @@ mod benchmarks {

// Move over to the build&earn subperiod to ensure 'non-loyal' staking.
// This is needed so we can achieve staker entry cleanup after claiming unlocked tokens.
advance_to_next_subperiod::<T>();
force_advance_to_next_subperiod::<T>();
assert_eq!(
ActiveProtocolState::<T>::get().subperiod(),
Subperiod::BuildAndEarn,
Expand Down Expand Up @@ -261,8 +266,18 @@ mod benchmarks {
);
let unlock_amount = unlock_amount * Into::<Balance>::into(T::MaxUnlockingChunks::get());

// Hack
// In order to speed up the benchmark, we reduce how long it takes to unlock the chunks
let mut counter = 1;
Ledger::<T>::mutate(&staker, |ledger| {
ledger.unlocking.iter_mut().for_each(|unlocking| {
unlocking.unlock_block = System::<T>::block_number() + counter;
});
counter += 1;
});

// Advance to next period to ensure the old stake entries are cleaned up.
advance_to_next_period::<T>();
force_advance_to_next_period::<T>();

// Additionally, ensure enough blocks have passed so that the unlocking chunk can be claimed.
let unlock_block = Ledger::<T>::get(&staker)
Expand Down Expand Up @@ -411,13 +426,9 @@ mod benchmarks {
}

#[benchmark]
fn claim_staker_rewards_past_period(x: Linear<1, { T::EraRewardSpanLength::get().min(8) }>) {
fn claim_staker_rewards_past_period(x: Linear<1, { T::EraRewardSpanLength::get() }>) {
initial_config::<T>();

// TODO: this benchmark needs to be improved since it's possible that
// we cannot stake because next era is part of the next period.
// Suggestion is to simplify it, and maybe allow custom benchmark params to be specified in the runtime.

// Prepare staker & register smart contract
let staker: T::AccountId = whitelisted_caller();
let owner: T::AccountId = account("dapp_owner", 0, SEED);
Expand All @@ -428,32 +439,50 @@ mod benchmarks {
smart_contract.clone(),
));

// Lock some amount by the staker
// Lock & stake some amount by the staker
let amount = T::MinimumLockedAmount::get();
T::BenchmarkHelper::set_balance(&staker, amount);
assert_ok!(DappStaking::<T>::lock(
RawOrigin::Signed(staker.clone()).into(),
amount,
));

// Advance to the era just before a new span entry is created.
// This ensures that when rewards are claimed, we'll be claiming from the new span.
//
// This is convenient because it allows us to control how many rewards are claimed.
advance_to_era::<T>(T::EraRewardSpanLength::get() - 1);

// Now ensure the expected amount of rewards are claimable.
advance_to_era::<T>(
ActiveProtocolState::<T>::get().era + T::EraRewardSpanLength::get() - x,
);
assert_ok!(DappStaking::<T>::stake(
RawOrigin::Signed(staker.clone()).into(),
smart_contract.clone(),
amount
));

// Advance to era just after the last era covered by the first span
force_advance_to_era::<T>(T::EraRewardSpanLength::get());

// Hack - modify staker's stake so it seems as if stake was valid from the 'first stake era'/
// Also fill up the reward span.
//
// This allows us to easily control how many rewards are claimed, without having to advance large amount of blocks/eras/periods
// to find an appropriate scenario.
let first_stake_era = T::EraRewardSpanLength::get() - x;
Ledger::<T>::mutate(&staker, |ledger| {
ledger.staked = ledger.staked_future.unwrap();
ledger.staked_future = None;
ledger.staked.era = first_stake_era;
});

// Just fill them up, the ledger entry will control how much claims we can make
let mut reward_span = EraRewardSpan::<_>::new();
for era in 0..(T::EraRewardSpanLength::get()) {
assert_ok!(reward_span.push(
era as EraNumber,
EraReward {
staker_reward_pool: 1_000_000_000_000,
staked: amount,
dapp_reward_pool: 1_000_000_000_000,
},
));
}
EraRewards::<T>::insert(&0, reward_span);

// This ensures we claim from the past period.
advance_to_next_period::<T>();
force_advance_to_next_period::<T>();

// For testing purposes
System::<T>::reset_events();
Expand All @@ -470,7 +499,7 @@ mod benchmarks {
}

#[benchmark]
fn claim_staker_rewards_ongoing_period(x: Linear<1, { T::EraRewardSpanLength::get().min(8) }>) {
fn claim_staker_rewards_ongoing_period(x: Linear<1, { T::EraRewardSpanLength::get() }>) {
initial_config::<T>();

// Prepare staker & register smart contract
Expand All @@ -490,25 +519,41 @@ mod benchmarks {
RawOrigin::Signed(staker.clone()).into(),
amount,
));

// Advance to the era just before a new span entry is created.
// This ensures that when rewards are claimed, we'll be claiming from the new span.
//
// This is convenient because it allows us to control how many rewards are claimed.
advance_to_era::<T>(T::EraRewardSpanLength::get() - 1);

// Now ensure the expected amount of rewards are claimable.
advance_to_era::<T>(
ActiveProtocolState::<T>::get().era + T::EraRewardSpanLength::get() - x,
);
assert_ok!(DappStaking::<T>::stake(
RawOrigin::Signed(staker.clone()).into(),
smart_contract.clone(),
amount
));

// This ensures we move over the entire span.
advance_to_era::<T>(T::EraRewardSpanLength::get() * 2);
// Advance to era just after the last era covered by the first span
// This means we'll be able to claim all of the rewards from the previous span.
force_advance_to_era::<T>(T::EraRewardSpanLength::get());

// Hack - modify staker's stake so it seems as if stake was valid from the 'first stake era'/
// Also fill up the reward span.
//
// This allows us to easily control how many rewards are claimed, without having to advance large amount of blocks/eras/periods
// to find an appropriate scenario.
let first_stake_era = T::EraRewardSpanLength::get() - x;
Ledger::<T>::mutate(&staker, |ledger| {
ledger.staked = ledger.staked_future.unwrap();
ledger.staked_future = None;
ledger.staked.era = first_stake_era;
});

// Just fill them up, the ledger entry will control how much claims we can make
let mut reward_span = EraRewardSpan::<_>::new();
for era in 0..(T::EraRewardSpanLength::get()) {
assert_ok!(reward_span.push(
era as EraNumber,
EraReward {
staker_reward_pool: 1_000_000_000_000,
staked: amount,
dapp_reward_pool: 1_000_000_000_000,
},
));
}
EraRewards::<T>::insert(&0, reward_span);

// For testing purposes
System::<T>::reset_events();
Expand Down Expand Up @@ -552,7 +597,7 @@ mod benchmarks {
));

// Advance to the next period so we can claim the bonus reward.
advance_to_next_period::<T>();
force_advance_to_next_period::<T>();

#[extrinsic_call]
_(RawOrigin::Signed(staker.clone()), smart_contract.clone());
Expand Down Expand Up @@ -615,7 +660,7 @@ mod benchmarks {
}

// Advance enough eras so dApp reward can be claimed.
advance_to_next_subperiod::<T>();
force_advance_to_next_subperiod::<T>();

// This is a hacky part to ensure we accomodate max number of contracts.
TierConfig::<T>::mutate(|config| {
Expand All @@ -625,7 +670,7 @@ mod benchmarks {
config.slots_per_tier[1..].iter_mut().for_each(|x| *x = 0);
config.tier_thresholds[0] = TierThreshold::FixedTvlAmount { amount: 1 };
});
advance_to_next_era::<T>();
force_advance_to_next_era::<T>();
let claim_era = ActiveProtocolState::<T>::get().era - 1;

assert_eq!(
Expand Down Expand Up @@ -700,7 +745,7 @@ mod benchmarks {
initial_config::<T>();

// Move over to the build&earn subperiod to ensure 'non-loyal' staking.
advance_to_next_subperiod::<T>();
force_advance_to_next_subperiod::<T>();

// Prepare staker & lock some amount
let staker: T::AccountId = whitelisted_caller();
Expand Down Expand Up @@ -730,7 +775,7 @@ mod benchmarks {
}

// Move over to the next period, marking the entries as expired since they don't have the loyalty flag.
advance_to_next_period::<T>();
force_advance_to_next_period::<T>();

#[extrinsic_call]
_(RawOrigin::Signed(staker.clone()));
Expand Down Expand Up @@ -796,7 +841,7 @@ mod benchmarks {
prepare_contracts_for_tier_assignment::<T>(max_number_of_contracts::<T>());

// Advance to build&earn subperiod
advance_to_next_subperiod::<T>();
force_advance_to_next_subperiod::<T>();
let snapshot_state = ActiveProtocolState::<T>::get();

// Advance over to the last era of the subperiod, and then again to the last block of that era.
Expand Down Expand Up @@ -845,11 +890,11 @@ mod benchmarks {
prepare_contracts_for_tier_assignment::<T>(max_number_of_contracts::<T>());

// Advance to build&earn subperiod
advance_to_next_subperiod::<T>();
force_advance_to_next_subperiod::<T>();
let snapshot_state = ActiveProtocolState::<T>::get();

// Advance over to the next era, and then again to the last block of that era.
advance_to_next_era::<T>();
force_advance_to_next_era::<T>();
run_to_block::<T>(ActiveProtocolState::<T>::get().next_era_start - 1);

// Some sanity checks, we should still be in the build&earn subperiod, and in the first period.
Expand Down Expand Up @@ -893,7 +938,7 @@ mod benchmarks {

// Register & stake contracts, to prepare for tier assignment.
prepare_contracts_for_tier_assignment::<T>(x);
advance_to_next_era::<T>();
force_advance_to_next_era::<T>();

let reward_era = ActiveProtocolState::<T>::get().era;
let reward_period = ActiveProtocolState::<T>::get().period_number();
Expand All @@ -912,9 +957,13 @@ mod benchmarks {
// Prepare init config (protocol state, tier params & config, etc.)
initial_config::<T>();

// Advance enough periods to trigger the cleanup
// Advance to era just after the last era covered by the first span.
// This is sufficient to completely fill up the first span with entries for the ongoing era.
force_advance_to_era::<T>(T::EraRewardSpanLength::get());

// Advance enough periods to make cleanup feasible.
let retention_period = T::RewardRetentionInPeriods::get();
advance_to_period::<T>(
force_advance_to_period::<T>(
ActiveProtocolState::<T>::get().period_number() + retention_period + 2,
);

Expand Down
Loading
Loading