Skip to content

Commit

Permalink
Tier config recalculation at the start of each era (#1230)
Browse files Browse the repository at this point in the history
* Tier config recalculation at the start of each era

* Keep mock price same as before

* Update pallets/dapp-staking-v3/src/test/tests.rs

Co-authored-by: Ashutosh Varma <[email protected]>

* Some weights, and benchmarks modification

* Shiden weights update

---------

Co-authored-by: Ashutosh Varma <[email protected]>
  • Loading branch information
Dinonard and ashutoshvarma authored May 2, 2024
1 parent 9f5e4dd commit 1722e4c
Show file tree
Hide file tree
Showing 8 changed files with 874 additions and 767 deletions.
3 changes: 3 additions & 0 deletions pallets/dapp-staking-v3/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,9 @@ mod benchmarks {
prepare_contracts_for_tier_assignment::<T>(x);
force_advance_to_next_era::<T>();

// Need to ensure settings remain unchanged even after the era change
init_tier_settings::<T>();

let reward_era = ActiveProtocolState::<T>::get().era;
let reward_period = ActiveProtocolState::<T>::get().period_number();
let reward_pool = Balance::from(10_000 * UNIT as u128);
Expand Down
10 changes: 7 additions & 3 deletions pallets/dapp-staking-v3/src/benchmarking/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,13 @@ pub(super) fn initial_config<T: Config>() {
maintenance: false,
});

// Init tier params
init_tier_settings::<T>();

Safeguard::<T>::put(false);
}

/// Set initial tier param & config
pub(super) fn init_tier_settings<T: Config>() {
let tier_params = TierParameters::<T::NumberOfTiers> {
reward_portion: BoundedVec::try_from(vec![
Permill::from_percent(40),
Expand Down Expand Up @@ -204,8 +210,6 @@ pub(super) fn initial_config<T: Config>() {

StaticTierParams::<T>::put(tier_params);
TierConfig::<T>::put(init_tier_config.clone());

Safeguard::<T>::put(false);
}

/// Maximum number of contracts that 'makes sense' - considers both contract number limit & number of slots.
Expand Down
13 changes: 6 additions & 7 deletions pallets/dapp-staking-v3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1902,13 +1902,6 @@ pub mod pallet {

era_info.migrate_to_next_era(Some(protocol_state.subperiod()));

// Re-calculate tier configuration for the upcoming new period
let tier_params = StaticTierParams::<T>::get();
let average_price = T::NativePriceProvider::average_price();
let new_tier_config =
TierConfig::<T>::get().calculate_new(average_price, &tier_params);
TierConfig::<T>::put(new_tier_config);

// Update historical cleanup marker.
// Must be called with the new period number.
Self::update_cleanup_marker(protocol_state.period_number());
Expand Down Expand Up @@ -1958,6 +1951,12 @@ pub mod pallet {
}
EraRewards::<T>::insert(&era_span_index, span);

// Re-calculate tier configuration for the upcoming new era
let tier_params = StaticTierParams::<T>::get();
let average_price = T::NativePriceProvider::average_price();
let new_tier_config = TierConfig::<T>::get().calculate_new(average_price, &tier_params);
TierConfig::<T>::put(new_tier_config);

Self::deposit_event(Event::<T>::NewEra { era: next_era });
if let Some(period_event) = maybe_period_event {
Self::deposit_event(period_event);
Expand Down
8 changes: 5 additions & 3 deletions pallets/dapp-staking-v3/src/test/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,14 @@ impl pallet_balances::Config for Test {
pub struct DummyPriceProvider;
impl PriceProvider for DummyPriceProvider {
fn average_price() -> FixedU128 {
FixedU128::from_rational(1, 10)
NATIVE_PRICE.with(|v| v.borrow().clone())
}
}

thread_local! {
pub(crate) static DOES_PAYOUT_SUCCEED: RefCell<bool> = RefCell::new(false);
pub(crate) static BLOCK_BEFORE_NEW_ERA: RefCell<EraNumber> = RefCell::new(0);
pub(crate) static NATIVE_PRICE: RefCell<FixedU128> = RefCell::new(FixedU128::from_rational(1, 10));
}

pub struct DummyStakingRewardHandler;
Expand Down Expand Up @@ -310,7 +311,7 @@ impl ExtBuilder {
.unwrap(),
};

// Init tier config, based on the initial params
// Init tier config, based on the initial params. Needs to be adjusted to the init price.
let init_tier_config = TiersConfiguration::<
<Test as Config>::NumberOfTiers,
<Test as Config>::TierSlots,
Expand All @@ -320,7 +321,8 @@ impl ExtBuilder {
reward_portion: tier_params.reward_portion.clone(),
tier_thresholds: tier_params.tier_thresholds.clone(),
_phantom: Default::default(),
};
}
.calculate_new(NATIVE_PRICE.with(|v| v.borrow().clone()), &tier_params);

pallet_dapp_staking::StaticTierParams::<Test>::put(tier_params);
pallet_dapp_staking::TierConfig::<Test>::put(init_tier_config.clone());
Expand Down
68 changes: 65 additions & 3 deletions pallets/dapp-staking-v3/src/test/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ use frame_support::{
fungible::Unbalanced as FunUnbalanced, Currency, Get, OnFinalize, OnInitialize,
ReservableCurrency,
},
BoundedVec,
};
use sp_runtime::traits::Zero;
use sp_runtime::{traits::Zero, FixedU128};

use astar_primitives::{
dapp_staking::{CycleConfiguration, EraNumber, SmartContractHandle},
Expand Down Expand Up @@ -2324,11 +2325,72 @@ fn force_with_safeguard_on_fails() {
})
}

#[test]
fn tier_config_recalculation_works() {
ExtBuilder::build().execute_with(|| {
let init_price = NATIVE_PRICE.with(|v| v.borrow().clone());
let init_tier_config = TierConfig::<Test>::get();

// 1. Advance to a new era, while keeping native price the same. Expect no change in the tier config
assert_ok!(DappStaking::force(RuntimeOrigin::root(), ForcingType::Era));
run_for_blocks(1);

assert_eq!(
init_tier_config,
TierConfig::<Test>::get(),
"Native price didn't change so tier config should remain the same."
);

// 2. Increase the native price, and expect number of tiers to be increased.
NATIVE_PRICE.with(|v| *v.borrow_mut() = init_price * FixedU128::from(3));

assert_ok!(DappStaking::force(RuntimeOrigin::root(), ForcingType::Era));
run_for_blocks(1);

let new_tier_config = TierConfig::<Test>::get();
assert!(
new_tier_config.number_of_slots > init_tier_config.number_of_slots,
"Price has increased, therefore number of slots must increase."
);
assert_eq!(
init_tier_config.slots_per_tier.len(),
new_tier_config.slots_per_tier.len(),
"Sanity check."
);
for idx in 0..init_tier_config.slots_per_tier.len() {
assert!(init_tier_config.slots_per_tier[idx] < new_tier_config.slots_per_tier[idx]);
}

// 3. Decrease the native price, and expect slots in tiers to be decreased.
NATIVE_PRICE.with(|v| *v.borrow_mut() = init_price * FixedU128::from_rational(1, 2));

assert_ok!(DappStaking::force(RuntimeOrigin::root(), ForcingType::Era));
run_for_blocks(1);

let new_tier_config = TierConfig::<Test>::get();
assert!(
new_tier_config.number_of_slots < init_tier_config.number_of_slots,
"Price has decreased, therefore number of slots must decrease."
);
assert_eq!(
init_tier_config.slots_per_tier.len(),
new_tier_config.slots_per_tier.len(),
"Sanity check."
);
for idx in 0..init_tier_config.slots_per_tier.len() {
assert!(init_tier_config.slots_per_tier[idx] > new_tier_config.slots_per_tier[idx]);
}
})
}

#[test]
fn get_dapp_tier_assignment_and_rewards_basic_example_works() {
ExtBuilder::build().execute_with(|| {
// This test will rely on the configuration inside the mock file.
// If that changes, this test will have to be updated as well.
// Tier config is specially adapted for this test.
TierConfig::<Test>::mutate(|config| {
config.number_of_slots = 40;
config.slots_per_tier = BoundedVec::try_from(vec![2, 5, 13, 20]).unwrap();
});

// Scenario:
// - 1st tier is filled up, with one dApp satisfying the threshold but not making it due to lack of tier capacity
Expand Down
Loading

0 comments on commit 1722e4c

Please sign in to comment.