Skip to content

Commit

Permalink
Set ProviderBoost capacity generated and fix tests (#1947)
Browse files Browse the repository at this point in the history
* set the amount of capacity generated by a provider boost to the final amount, 50% of what is generated by MaximizedCapacity staking.
* Also Fixes some tests broken from the last rebase with main.
Closes #1569
  • Loading branch information
shannonwells committed May 22, 2024
1 parent 8c74ad4 commit bd509dd
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 102 deletions.
39 changes: 23 additions & 16 deletions pallets/capacity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ mod tests;
/// storage migrations
pub mod migration;
pub mod weights;
type BalanceOf<T> =
pub(crate) type BalanceOf<T> =
<<T as Config>::Currency as InspectFungible<<T as frame_system::Config>::AccountId>>::Balance;

use frame_system::pallet_prelude::*;
use crate::StakingType::{MaximumCapacity, ProviderBoost};

#[frame_support::pallet]
pub mod pallet {
Expand Down Expand Up @@ -411,6 +412,9 @@ pub mod pallet {
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(current: BlockNumberFor<T>) -> Weight {
Self::start_new_epoch_if_needed(current)
.saturating_add(
Self::start_new_reward_era_if_needed(current)
)
}
}

Expand All @@ -433,7 +437,7 @@ pub mod pallet {
let staker = ensure_signed(origin)?;

let (mut staking_account, actual_amount) =
Self::ensure_can_stake(&staker, target, amount)?;
Self::ensure_can_stake(&staker, target, amount, MaximumCapacity)?;

let capacity = Self::increase_stake_and_issue_capacity(
&staker,
Expand Down Expand Up @@ -616,18 +620,21 @@ impl<T: Config> Pallet<T> {
staker: &T::AccountId,
target: MessageSourceId,
amount: BalanceOf<T>,
staking_type: StakingType,
) -> Result<(StakingDetails<T>, BalanceOf<T>), DispatchError> {
ensure!(amount > Zero::zero(), Error::<T>::ZeroAmountNotAllowed);
ensure!(T::TargetValidator::validate(target), Error::<T>::InvalidTarget);

let staking_account = Self::get_staking_account_for(&staker).unwrap_or_default();
ensure!(staking_account.staking_type.ne(&StakingType::ProviderBoost), Error::<T>::CannotChangeStakingType);
let staking_details = Self::get_staking_account_for(&staker).unwrap_or_default();
if !staking_details.active.is_zero() {
ensure!(staking_details.staking_type.eq(&staking_type), Error::<T>::CannotChangeStakingType);
}

let stakable_amount = Self::get_stakable_amount_for(&staker, amount);

ensure!(stakable_amount > Zero::zero(), Error::<T>::BalanceTooLowtoStake);

let new_active_staking_amount = staking_account
let new_active_staking_amount = staking_details
.active
.checked_add(&stakable_amount)
.ok_or(ArithmeticError::Overflow)?;
Expand All @@ -637,18 +644,20 @@ impl<T: Config> Pallet<T> {
Error::<T>::StakingAmountBelowMinimum
);

Ok((staking_account, stakable_amount))
Ok((staking_details, stakable_amount))
}

// TODO: this should return StakingAccount, BoostHistory and Balance
fn ensure_can_boost(
staker: &T::AccountId,
target: &MessageSourceId,
amount: &BalanceOf<T>,
) -> Result<(StakingDetails<T>, BalanceOf<T>), DispatchError> {
let (staking_details, stakable_amount) = Self::ensure_can_stake(staker, *target, *amount)?;
// TODO: boost history
// let boost_history = Self::get_boost_history_for(staker).unwrap_or_defaul();
// FIXME: if one is boosting additional amounts, this will fail.
let (mut staking_details, stakable_amount) =
Self::ensure_can_stake(staker, *target, *amount, ProviderBoost)?;
staking_details.staking_type = ProviderBoost;
// TODO: update when boost history is implemented fully
// let boost_history = Self::get_boost_history_for(staker).unwrap_or_default();
Ok((staking_details, stakable_amount))
}

Expand Down Expand Up @@ -677,7 +686,6 @@ impl<T: Config> Pallet<T> {
Ok(capacity)
}

// TODO:
fn increase_stake_and_issue_boost(
staker: &T::AccountId,
staking_details: &mut StakingDetails<T>,
Expand All @@ -688,17 +696,17 @@ impl<T: Config> Pallet<T> {
.deposit(*amount)
.ok_or(ArithmeticError::Overflow)?;

// get the capacity generated by a Provider Boost
let capacity = Self::capacity_generated(T::RewardsProvider::capacity_boost(*amount));

// TODO: target details added fields
let mut target_details = Self::get_target_for(staker, target).unwrap_or_default();

target_details.deposit(*amount, capacity).ok_or(ArithmeticError::Overflow)?;

let mut capacity_details = Self::get_capacity_for(target).unwrap_or_default();
capacity_details.deposit(amount, &capacity).ok_or(ArithmeticError::Overflow)?;

// TODO: add boost history record for era
// TODO: add boost history record for era when boost history is implemented
// let era = Self::get_current_era().era_index;
Self::set_staking_account_and_lock(staker, staking_details)?;
Self::set_target_details_for(staker, *target, target_details);
Expand Down Expand Up @@ -731,7 +739,7 @@ impl<T: Config> Pallet<T> {
}

/// If the staking account total is zero we reap storage, otherwise set the account to the new details.
// TODO: do not remove this lock unless both types of staking account details are cleared.
// TODO: do not remove this lock unless both types of staking details are cleared.
// fn delete_boosting_account(staker: &T::AccountId) {
// // otherwise call set_lock for the new value containing only the other type of staking account.
// T::Currency::remove_lock(STAKING_ID, &staker);
Expand Down Expand Up @@ -962,7 +970,6 @@ impl<T: Config> Pallet<T> {

/// Returns whether `account_id` may claim and and be paid token rewards.
pub fn payout_eligible(account_id: T::AccountId) -> bool {
// TODO: stake vs boost
let _staking_account =
Self::get_staking_account_for(account_id).ok_or(Error::<T>::NotAStakingAccount);
false
Expand Down Expand Up @@ -1129,6 +1136,6 @@ impl<T: Config> StakingRewardsProvider<T> for Pallet<T> {

/// How much, as a percentage of staked token, to boost a targeted Provider when staking.
fn capacity_boost(amount: BalanceOf<T>) -> BalanceOf<T> {
Perbill::from_percent(5u32).mul(amount)
Perbill::from_percent(50u32).mul(amount)
}
}
1 change: 0 additions & 1 deletion pallets/capacity/src/migration/provider_boost_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use frame_support::{
use frame_support::{
traits::Get,
};
use sp_runtime::TryRuntimeError;

#[cfg(feature = "try-runtime")]
use sp_std::vec::Vec;
Expand Down
39 changes: 14 additions & 25 deletions pallets/capacity/src/tests/change_staking_target_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,8 @@ use super::{
mock::*,
testing_utils::{setup_provider, staking_events},
};
use crate::{
BalanceOf, CapacityDetails, Config, CurrentEraInfo, Error, Event, RetargetInfo, RewardEraInfo,
StakingAccountDetails, StakingAccountLedger, StakingTargetDetails,
};
use crate::*;
use common_primitives::{
capacity::{
StakingType,
StakingType::{MaximumCapacity, ProviderBoost},
},
msa::MessageSourceId,
};
use frame_support::{assert_noop, assert_ok, traits::Get};
Expand Down Expand Up @@ -40,10 +33,9 @@ fn assert_target_details(
msa_id: MessageSourceId,
amount: u64,
capacity: u64,
staking_type: StakingType,
) {
let expected_from_target_details: TestTargetDetails =
StakingTargetDetails { amount, capacity, staking_type };
StakingTargetDetails { amount, capacity };
let from_target_details = Capacity::get_target_for(staker, msa_id).unwrap();
assert_eq!(from_target_details, expected_from_target_details);
}
Expand All @@ -61,17 +53,17 @@ fn do_retarget_happy_path() {
setup_provider(&staker, &to_msa, &to_amount, staking_type.clone());

// retarget half the stake to to_msa
assert_ok!(Capacity::do_retarget(&staker, &from_msa, &to_msa, &to_amount, &staking_type));
assert_ok!(Capacity::do_retarget(&staker, &from_msa, &to_msa, &to_amount));

// expect from stake amounts to be halved
assert_capacity_details(from_msa, 1, 300, 1);

// expect to stake amounts to be increased by the retarget amount
assert_capacity_details(to_msa, 3, 600, 3);

assert_target_details(staker, from_msa, 300, 1, staking_type.clone());
assert_target_details(staker, from_msa, 300, 1);

assert_target_details(staker, to_msa, 600, 3, staking_type.clone());
assert_target_details(staker, to_msa, 600, 3);
})
}

Expand All @@ -93,15 +85,13 @@ fn do_retarget_flip_flop() {
&from_msa,
&to_msa,
&to_amount,
&ProviderBoost
));
} else {
assert_ok!(Capacity::do_retarget(
&staker,
&to_msa,
&from_msa,
&to_amount,
&ProviderBoost
));
}
}
Expand All @@ -126,12 +116,12 @@ fn check_retarget_rounding_errors() {
assert_capacity_details(to_msa, 1, 301, 1);
// 666+301= 967, 3+1=4

assert_ok!(Capacity::do_retarget(&staker, &from_msa, &to_msa, &301u64, &ProviderBoost));
assert_ok!(Capacity::do_retarget(&staker, &from_msa, &to_msa, &301u64));
assert_capacity_details(to_msa, 3, 602, 3);
assert_capacity_details(from_msa, 1, 365, 1);
// 602+365 = 967, 3+1 = 4

assert_ok!(Capacity::do_retarget(&staker, &to_msa, &from_msa, &151u64, &ProviderBoost));
assert_ok!(Capacity::do_retarget(&staker, &to_msa, &from_msa, &151u64));
assert_capacity_details(to_msa, 2, 451, 2);
assert_capacity_details(from_msa, 2, 516, 2);
// 451+516 = 967, 2+2 = 4
Expand Down Expand Up @@ -174,10 +164,10 @@ fn check_retarget_multiple_stakers() {
// total capacity should be 73
assert_total_capacity(vec![from_msa, to_msa], 73);

assert_ok!(Capacity::do_retarget(&staker_10k, &from_msa, &to_msa, &amt2, &ProviderBoost));
assert_ok!(Capacity::do_retarget(&staker_600, &from_msa, &to_msa, &amt1, &MaximumCapacity));
assert_ok!(Capacity::do_retarget(&staker_500, &to_msa, &from_msa, &amt1, &ProviderBoost));
assert_ok!(Capacity::do_retarget(&staker_400, &to_msa, &from_msa, &amt1, &MaximumCapacity));
assert_ok!(Capacity::do_retarget(&staker_10k, &from_msa, &to_msa, &amt2));
assert_ok!(Capacity::do_retarget(&staker_600, &from_msa, &to_msa, &amt1));
assert_ok!(Capacity::do_retarget(&staker_500, &to_msa, &from_msa, &amt1));
assert_ok!(Capacity::do_retarget(&staker_400, &to_msa, &from_msa, &amt1));
assert_total_capacity(vec![from_msa, to_msa], 73);
})
}
Expand All @@ -196,7 +186,7 @@ fn do_retarget_deletes_staking_target_details_if_zero_balance() {
// total staked to from_msa is now 22u64.
assert_ok!(Capacity::stake(RuntimeOrigin::signed(300u64), from_msa, 12u64,));

assert_ok!(Capacity::do_retarget(&staker, &from_msa, &to_msa, &amount, &MaximumCapacity));
assert_ok!(Capacity::do_retarget(&staker, &from_msa, &to_msa, &amount));

let expected_from_details: TestCapacityDetails = CapacityDetails {
remaining_capacity: 1,
Expand All @@ -223,7 +213,6 @@ fn do_retarget_deletes_staking_target_details_if_zero_balance() {
let expected_to_target_details: TestTargetDetails = StakingTargetDetails {
amount: 2 * amount,
capacity: 2,
staking_type: StakingType::MaximumCapacity,
};
let to_target_details = Capacity::get_target_for(staker, to_msa).unwrap();
assert_eq!(to_target_details, expected_to_target_details);
Expand Down Expand Up @@ -271,7 +260,7 @@ fn change_staking_target_errors_if_too_many_changes_before_thaw() {
setup_provider(&staker, &to_msa, &10u64, ProviderBoost);

let retarget_amount = 10u64;
for _i in 0..(max_chunks) {
for _i in 0..max_chunks {
assert_ok!(Capacity::change_staking_target(
RuntimeOrigin::signed(staker),
from_msa,
Expand Down Expand Up @@ -330,7 +319,7 @@ fn change_staking_target_test_parametric_validity() {

StakingAccountLedger::<Test>::insert(
from_account,
StakingAccountDetails { active: 20, total: 20, unlocking: Default::default() },
StakingDetails { active: 20, staking_type: ProviderBoost },
);
let from_account_not_staking = 100u64;
let from_target_not_staked: MessageSourceId = 1;
Expand Down
2 changes: 1 addition & 1 deletion pallets/capacity/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate as pallet_capacity;

use crate::{BalanceOf, StakingRewardClaim, StakingRewardsProvider};
use common_primitives::{
node::{AccountId, Hash, Header, ProposalProvider},
node::{AccountId, Hash, ProposalProvider},
schema::{SchemaId, SchemaValidator},
};
use frame_support::{
Expand Down
4 changes: 4 additions & 0 deletions pallets/capacity/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
pub mod capacity_details_tests;
mod change_staking_target_tests;
pub mod epochs_tests;
mod eras_tests;
mod migrate_v2_tests;
pub mod mock;
pub mod other_tests;
mod provider_boost_tests;
pub mod replenishment_tests;
mod rewards_provider_tests;
pub mod stake_and_deposit_tests;
pub mod staking_account_details_tests;
pub mod staking_target_details_tests;
Expand Down
65 changes: 19 additions & 46 deletions pallets/capacity/src/tests/provider_boost_tests.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use super::{mock::*, testing_utils::*};
use crate::{
BoostingAccountDetails, Error, Event, RewardPoolInfo, StakingAccountDetails, StakingHistory,
};
use common_primitives::{capacity::StakingType::ProviderBoost, msa::MessageSourceId};
use crate::{StakingDetails, Error, Event, StakingType, FreezeReason};
use common_primitives::{msa::MessageSourceId};
use frame_support::{
assert_noop, assert_ok,
traits::{Len, WithdrawReasons},
assert_noop, assert_ok, traits::fungible::InspectFreeze
};
use crate::Config;

#[test]
fn provider_boost_works() {
Expand All @@ -19,27 +17,29 @@ fn provider_boost_works() {
assert_ok!(Capacity::provider_boost(RuntimeOrigin::signed(account), target, amount));

// Check that StakingAccountLedger is updated.
let boost_account: BoostingAccountDetails<Test> =
Capacity::get_boost_details_for(account).unwrap();
let boost_account: StakingDetails<Test> =
Capacity::get_staking_account_for(account).unwrap();

assert_eq!(boost_account.staking_details.total, 200);
assert_eq!(boost_account.staking_details.active, 200);
// assert_eq!(boost_account.unlocking.len(), 0);
// assert_eq!(staking_account.last_rewards_claimed_at, None);
// assert_eq!(staking_account.stake_change_unlocking.len(), 0);
// Check that the staking account has the correct staking type.
assert_eq!(boost_account.active, 200);
assert_eq!(boost_account.staking_type, StakingType::ProviderBoost);

// Check that the capacity generated is correct. (5% of amount staked, since 10% is what's in the mock)
let capacity_details = Capacity::get_capacity_for(target).unwrap();
assert_eq!(capacity_details.total_capacity_issued, 1u64);

let events = staking_events();
assert_eq!(
events.first().unwrap(),
&Event::ProviderBoosted { account, target, amount, capacity }
);

assert_eq!(Balances::locks(&account)[0].amount, amount);
assert_eq!(Balances::locks(&account)[0].reasons, WithdrawReasons::all().into());
assert_eq!(<Test as Config>::Currency::balance_frozen(&FreezeReason::CapacityStaking.into(), &account),
200u64
);

let target_details = Capacity::get_target_for(account, target).unwrap();
assert_eq!(target_details.amount, amount);
assert_eq!(target_details.staking_type, ProviderBoost);
});
}

Expand All @@ -51,39 +51,12 @@ fn provider_boost_updates_boost_account_details() {
let amount = 500;
register_provider(target, String::from("Foo"));
assert_ok!(Capacity::provider_boost(RuntimeOrigin::signed(account), target, amount));
let boost_details: BoostingAccountDetails<Test> =
Capacity::get_boost_details_for(account).unwrap();
assert_eq!(boost_details.staking_details.active, 500);
assert_eq!(boost_details.staking_details.total, 500);
assert!(boost_details.last_rewards_claimed_at.is_none());
assert_eq!(boost_details.boost_history.len(), 1);

let expected_history = StakingHistory { reward_era: 0, total_staked: 500 };
let actual_history = boost_details.boost_history.get(0).unwrap();
assert_eq!(actual_history, &expected_history);
let boost_details: StakingDetails<Test> =
Capacity::get_staking_account_for(account).unwrap();
assert_eq!(boost_details.active, 500);
})
}

#[test]
fn provider_boost_adjusts_reward_pool_total() {
new_test_ext().execute_with(|| {
// TODO: when work resumes on reward pool branch
// let account = 600;
// let target: MessageSourceId = 1;
// let amount = 500;
// register_provider(target, String::from("Foo"));
// assert_ok!(Capacity::provider_boost(RuntimeOrigin::signed(account), target, amount));
//
// let reward_pool_info = Capacity::get_reward_pool_for_era(0).unwrap();
// assert_eq!(reward_pool_info, RewardPoolInfo {
// total_staked_token: 500,
// total_reward_pool: 50,
// unclaimed_balance: 50,
// });
assert!(true);
});
}

#[test]
fn calling_stake_on_provider_boost_target_errors() {
new_test_ext().execute_with(|| {
Expand Down
Loading

0 comments on commit bd509dd

Please sign in to comment.