Skip to content

Commit

Permalink
feat: add block rewards to altair and centrifuge runtimes (#1342)
Browse files Browse the repository at this point in the history
* feat: add ED funding to rewards pallet

* feat: apply reward genesis config to dev runtime

* tests: apply rewards ED to block rewards

* tests: add sanity intgr block rewards check

* feat: add block rewards to altair runtime

* feat: add block rewards to cfg runtime

* docs: improve blk rw migraton com

* feat: reduce collator kick threshold to 2 hours

* Revert "feat: reduce collator kick threshold to 2 hours"

This reverts commit afc4d54.

* fix: re-enable transfer keep alive

* fix: chain_spec

* refactor: move rewards migration

* feat: add session key migration

* fix: mixed up tokens in spec

* refactor: rm dev migrations

* bench: fix block rewards

* refactor: move migrations to sep file

* refactor: block rewards pallet id

* refactor: improve pallet genesis build err log

* refactor: remove rewards domain concept (#1344)

* refactor: remove rewards domain concept

* refactor: rm dev migrations

* refactor: remove DOM

* bench: fix block rewards

* fix: RewardsApi

* refactor: rename LiquidityRewardsBase

* tests: add block rewards RAPI int

* clippy: remove unused

* fmt: taplo

* fix: dev chainspec after renaming

* refactor: apply suggestion from code review

* Update runtime/centrifuge/src/lib.rs

Co-authored-by: Frederik Gartenmeister <[email protected]>

---------

Co-authored-by: Frederik Gartenmeister <[email protected]>
  • Loading branch information
wischli and mustermeiszer authored May 16, 2023
1 parent 8b811de commit 629dcfd
Show file tree
Hide file tree
Showing 40 changed files with 1,417 additions and 575 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libs/types/src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub const CROWDLOAN_CLAIM_PALLET_ID: PalletId = PalletId(*b"cc/claim");
pub const TREASURY_PALLET_ID: PalletId = PalletId(*b"py/trsry");
pub const NFT_SALES_PALLET_ID: PalletId = PalletId(*b"pal/nfts");
pub const STAKE_POT_PALLET_ID: PalletId = PalletId(*b"PotStake");
pub const BLOCK_REWARDS_PALLET_ID: PalletId = PalletId(*b"cfg/blrw");

// Other ids
pub const CHAIN_BRIDGE_HASH_ID: [u8; 13] = *b"cent_nft_hash";
Expand Down
10 changes: 5 additions & 5 deletions pallets/block-rewards/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ benchmarks! {
assert!(T::Rewards::is_ready(T::StakeGroupId::get()));
assert!(
!T::Rewards::compute_reward(
(
T::Domain::get(),
T::StakeCurrencyId::get(),
),
T::StakeCurrencyId::get(),
&beneficiary,
).unwrap().is_zero()
);
let before = <T as Config>::Currency::balance(CurrencyId::Native.into(), &beneficiary);

}: _(RawOrigin::Signed(caller), beneficiary.clone())
verify {
let num_collators: u128 = BlockRewards::<T>::next_session_changes().collator_count.unwrap_or(
BlockRewards::<T>::active_session_data().collator_count
).into();
// Does not get entire reward since another collator is auto-staked via genesis config
assert_eq!(<T as Config>::Currency::balance(CurrencyId::Native.into(), &beneficiary).saturating_sub(before), (REWARD / 2).into());
assert_eq!(<T as Config>::Currency::balance(CurrencyId::Native.into(), &beneficiary).saturating_sub(before), (REWARD / (num_collators + 1)).into());
}

set_collator_reward {
Expand Down
38 changes: 10 additions & 28 deletions pallets/block-rewards/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ pub struct SessionChanges<T: Config> {
total_reward: Option<T::Balance>,
}

pub(crate) type DomainIdOf<T> = <<T as Config>::Domain as TypedGet>::Type;
pub(crate) type NegativeImbalanceOf<T> = <<T as Config>::Currency as CurrencyT<
<T as frame_system::Config>::AccountId,
>>::NegativeImbalance;
Expand All @@ -131,9 +130,6 @@ pub mod pallet {
+ Into<<<Self as Config>::Currency as CurrencyT<Self::AccountId>>::Balance>
+ MaybeSerializeDeserialize;

/// Domain identification used by this pallet
type Domain: TypedGet;

/// Type used to handle group weights.
type Weight: Parameter + MaxEncodedLen + EnsureAdd + Unsigned + FixedPointOperand + Default;

Expand All @@ -142,11 +138,8 @@ pub mod pallet {
+ AccountRewards<
Self::AccountId,
Balance = Self::Balance,
CurrencyId = (DomainIdOf<Self>, <Self as Config>::CurrencyId),
> + CurrencyGroupChange<
GroupId = u32,
CurrencyId = (DomainIdOf<Self>, <Self as Config>::CurrencyId),
>;
CurrencyId = <Self as Config>::CurrencyId,
> + CurrencyGroupChange<GroupId = u32, CurrencyId = <Self as Config>::CurrencyId>;

/// The type used to handle currency minting and burning for collators.
type Currency: Mutate<Self::AccountId, AssetId = <Self as Config>::CurrencyId, Balance = Self::Balance>
Expand Down Expand Up @@ -258,12 +251,9 @@ pub mod pallet {
#[pallet::genesis_build]
impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
fn build(&self) {
T::Rewards::attach_currency(
(T::Domain::get(), T::StakeCurrencyId::get()),
T::StakeGroupId::get(),
)
.map_err(|e| log::error!("Failed to attach currency to collator group: {:?}", e))
.ok();
T::Rewards::attach_currency(T::StakeCurrencyId::get(), T::StakeGroupId::get()).expect(
"Should be able to attach default block rewards staking currency to collator group",
);

ActiveSessionData::<T>::mutate(|session_data| {
session_data.collator_count = self.collators.len().saturated_into();
Expand All @@ -274,10 +264,7 @@ pub mod pallet {
// Enables rewards already in genesis session.
for collator in &self.collators {
Pallet::<T>::do_init_collator(collator)
.map_err(|e| {
log::error!("Failed to init genesis collators for rewards: {:?}", e);
})
.ok();
.expect("Should not panic when initiating genesis collators for block rewards");
}
}
}
Expand All @@ -291,8 +278,7 @@ pub mod pallet {
pub fn claim_reward(origin: OriginFor<T>, account_id: T::AccountId) -> DispatchResult {
ensure_signed(origin)?;

T::Rewards::claim_reward((T::Domain::get(), T::StakeCurrencyId::get()), &account_id)
.map(|_| ())
T::Rewards::claim_reward(T::StakeCurrencyId::get(), &account_id).map(|_| ())
}

/// Admin method to set the reward amount for a collator used for the
Expand Down Expand Up @@ -369,18 +355,14 @@ impl<T: Config> Pallet<T> {
/// Account
pub(crate) fn do_init_collator(who: &T::AccountId) -> DispatchResult {
T::Currency::mint_into(T::StakeCurrencyId::get(), who, T::StakeAmount::get())?;
T::Rewards::deposit_stake(
(T::Domain::get(), T::StakeCurrencyId::get()),
who,
T::StakeAmount::get(),
)
T::Rewards::deposit_stake(T::StakeCurrencyId::get(), who, T::StakeAmount::get())
}

/// Withdraw currently staked amount for target address and immediately burn
/// it. Disables receiving rewards onwards.
pub(crate) fn do_exit_collator(who: &T::AccountId) -> DispatchResult {
let amount = T::Rewards::account_stake((T::Domain::get(), T::StakeCurrencyId::get()), who);
T::Rewards::withdraw_stake((T::Domain::get(), T::StakeCurrencyId::get()), who, amount)?;
let amount = T::Rewards::account_stake(T::StakeCurrencyId::get(), who);
T::Rewards::withdraw_stake(T::StakeCurrencyId::get(), who, amount)?;
T::Currency::burn_from(T::StakeCurrencyId::get(), who, amount).map(|_| ())
}

Expand Down
15 changes: 4 additions & 11 deletions pallets/block-rewards/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use frame_support::{
pallet_prelude::{StorageVersion, Weight},
traits::{Get, OnRuntimeUpgrade},
};
use sp_runtime::{traits::TypedGet, BoundedVec, SaturatedConversion};
use sp_runtime::{BoundedVec, SaturatedConversion};
use sp_std::marker::PhantomData;
#[cfg(feature = "try-runtime")]
use {
Expand Down Expand Up @@ -84,10 +84,7 @@ where
weight.saturating_accrue(T::DbWeight::get().reads(2));

<T as Config>::Rewards::attach_currency(
(
<T as Config>::Domain::get(),
<T as Config>::StakeCurrencyId::get(),
),
<T as Config>::StakeCurrencyId::get(),
<T as Config>::StakeGroupId::get(),
)
.map_err(|e| log::error!("Failed to attach currency to collator group: {:?}", e))
Expand All @@ -101,8 +98,7 @@ where
weight.saturating_accrue(T::DbWeight::get().writes(1));

for collator in collators.iter() {
// TODO: Benching preferred to be precise.
// However, not necessarily needed as num of collators <= 10.
// NOTE: Benching not required as num of collators <= 10.
Pallet::<T>::do_init_collator(collator)
.map_err(|e| {
log::error!("Failed to init genesis collators for rewards: {:?}", e);
Expand Down Expand Up @@ -142,10 +138,7 @@ where

for collator in collators.iter() {
assert!(!<T as Config>::Rewards::account_stake(
(
<T as Config>::Domain::get(),
<T as Config>::StakeCurrencyId::get(),
),
<T as Config>::StakeCurrencyId::get(),
collator,
)
.is_zero())
Expand Down
28 changes: 10 additions & 18 deletions pallets/block-rewards/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use cfg_traits::rewards::AccountRewards;
use cfg_types::tokens::{CurrencyId, StakingCurrency::BlockRewards as BlockRewardsCurrency};
use codec::MaxEncodedLen;
use frame_support::{
parameter_types,
traits::{
Expand Down Expand Up @@ -115,7 +114,7 @@ impl pallet_session::Config for Test {
}

parameter_types! {
pub const ExistentialDeposit: Balance = 0;
pub const ExistentialDeposit: Balance = 1;
}
impl pallet_balances::Config for Test {
type AccountStore = System;
Expand Down Expand Up @@ -182,16 +181,8 @@ impl pallet_restricted_tokens::Config for Test {
type WeightInfo = ();
}

#[derive(
scale_info::TypeInfo, Debug, Copy, codec::Encode, codec::Decode, PartialEq, Clone, MaxEncodedLen,
)]
pub enum RewardDomain {
Liquidity,
Block,
}

frame_support::parameter_types! {
pub const RewardsPalletId: PalletId = PalletId(*b"d/reward");
pub const RewardsPalletId: PalletId = cfg_types::ids::BLOCK_REWARDS_PALLET_ID;
pub const NativeToken: CurrencyId = CurrencyId::Native;

#[derive(scale_info::TypeInfo)]
Expand All @@ -201,7 +192,6 @@ frame_support::parameter_types! {
impl pallet_rewards::Config<pallet_rewards::Instance1> for Test {
type Currency = Tokens;
type CurrencyId = CurrencyId;
type DomainId = RewardDomain;
type GroupId = u32;
type PalletId = RewardsPalletId;
type RewardCurrency = NativeToken;
Expand All @@ -227,7 +217,6 @@ frame_support::parameter_types! {
pub const MaxChangesPerSession: u32 = 50;
#[derive(scale_info::TypeInfo, Debug, PartialEq, Clone)]
pub const MaxCollators: u32 = MAX_COLLATORS;
pub const BlockRewardsDomain: RewardDomain = RewardDomain::Block;
pub const BlockRewardCurrency: CurrencyId = CurrencyId::Staking(BlockRewardsCurrency);
pub const StakeAmount: Balance = cfg_types::consts::rewards::DEFAULT_COLLATOR_STAKE;
pub const CollatorGroupId: u32 = cfg_types::ids::COLLATOR_GROUP_ID;
Expand All @@ -240,7 +229,6 @@ impl pallet_block_rewards::Config for Test {
type Beneficiary = RewardRemainderMock;
type Currency = Tokens;
type CurrencyId = CurrencyId;
type Domain = BlockRewardsDomain;
type MaxChangesPerSession = MaxChangesPerSession;
type MaxCollators = MaxCollators;
type Rewards = Rewards;
Expand All @@ -265,10 +253,7 @@ pub(crate) fn assert_staked(who: &AccountId) {

pub(crate) fn assert_not_staked(who: &AccountId) {
assert!(<Test as Config>::Rewards::account_stake(
(
<Test as Config>::Domain::get(),
<Test as Config>::StakeCurrencyId::get()
),
<Test as Config>::StakeCurrencyId::get(),
who
)
.is_zero());
Expand Down Expand Up @@ -378,6 +363,13 @@ impl ExtBuilder {
.assimilate_storage(&mut storage)
.expect("Session pallet's storage can be assimilated");

pallet_rewards::GenesisConfig::<Test, pallet_rewards::Instance1> {
currency_id: CurrencyId::Native,
amount: ExistentialDeposit::get(),
}
.assimilate_storage(&mut storage)
.expect("Rewards pallet's storage can be assimilated");

let mut ext = sp_io::TestExternalities::new(storage);

ext.execute_with(|| {
Expand Down
Loading

0 comments on commit 629dcfd

Please sign in to comment.