diff --git a/node/service/src/chain_spec/bifrost_kusama.rs b/node/service/src/chain_spec/bifrost_kusama.rs index ba38b8ab7..4a307e7ea 100644 --- a/node/service/src/chain_spec/bifrost_kusama.rs +++ b/node/service/src/chain_spec/bifrost_kusama.rs @@ -18,13 +18,13 @@ use crate::chain_spec::{get_account_id_from_seed, get_from_seed, RelayExtensions}; use bifrost_kusama_runtime::{ - constants::currency::DOLLARS, AccountId, Balance, BalancesConfig, BlockNumber, - DefaultBlocksPerRound, InflationInfo, Range, SS58Prefix, VestingConfig, + constants::currency::DOLLARS, AccountId, Balance, BalancesConfig, BlockNumber, InflationInfo, + Range, SS58Prefix, VestingConfig, }; use bifrost_primitives::{ BifrostKusamaChainId, CurrencyId, CurrencyId::*, TokenInfo, TokenSymbol::*, }; -use bifrost_runtime_common::AuraId; +use bifrost_runtime_common::{constants::time::HOURS, AuraId}; use cumulus_primitives_core::ParaId; use frame_benchmarking::{account, whitelisted_caller}; use hex_literal::hex; @@ -33,7 +33,7 @@ use sc_service::ChainType; use serde::de::DeserializeOwned; use serde_json as json; use sp_core::{crypto::UncheckedInto, sr25519}; -use sp_runtime::{traits::Zero, Perbill}; +use sp_runtime::{traits::Zero, Perbill, Percent}; use std::{ collections::BTreeMap, fs::{read_dir, File}, @@ -50,6 +50,10 @@ pub fn ENDOWMENT() -> u128 { 1_000_000 * DOLLARS } +const COLLATOR_COMMISSION: Perbill = Perbill::from_percent(10); +const PARACHAIN_BOND_RESERVE_PERCENT: Percent = Percent::from_percent(0); +const BLOCKS_PER_ROUND: u32 = 2 * HOURS; + pub fn inflation_config() -> InflationInfo { fn to_round_inflation(annual: Range) -> Range { use bifrost_parachain_staking::inflation::{ @@ -58,7 +62,7 @@ pub fn inflation_config() -> InflationInfo { perbill_annual_to_perbill_round( annual, // rounds per year - BLOCKS_PER_YEAR / DefaultBlocksPerRound::get(), + BLOCKS_PER_YEAR / BLOCKS_PER_ROUND, ) } let annual = Range { @@ -171,6 +175,9 @@ pub fn bifrost_genesis( .collect::>(), "delegations": delegations, "inflationConfig": inflation_config(), + "collatorCommission": COLLATOR_COMMISSION, + "parachainBondReservePercent": PARACHAIN_BOND_RESERVE_PERCENT, + "blocksPerRound": BLOCKS_PER_ROUND, }, }) } diff --git a/pallets/buy-back/src/lib.rs b/pallets/buy-back/src/lib.rs index b3ea80623..f6668d663 100644 --- a/pallets/buy-back/src/lib.rs +++ b/pallets/buy-back/src/lib.rs @@ -270,6 +270,7 @@ pub mod pallet { n.saturating_sub(info.last_buyback_cycle) .saturated_into::() .saturating_sub(One::one()) => + { if let Some(swap_out_min) = SwapOutMin::::get(currency_id) { if let Some(e) = Self::buy_back(&buyback_address, currency_id, &info, swap_out_min) @@ -295,7 +296,8 @@ pub mod pallet { info.last_buyback = n; Infos::::insert(currency_id, info); SwapOutMin::::remove(currency_id); - }, + } + }, _ => (), } } diff --git a/pallets/parachain-staking/Cargo.toml b/pallets/parachain-staking/Cargo.toml index c9a7d34b9..04aa346cd 100644 --- a/pallets/parachain-staking/Cargo.toml +++ b/pallets/parachain-staking/Cargo.toml @@ -46,6 +46,7 @@ std = [ "pallet-authorship/std", "pallet-session/std", "log/std", + "bifrost-primitives/std", ] runtime-benchmarks = ["frame-benchmarking"] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/parachain-staking/src/inflation.rs b/pallets/parachain-staking/src/inflation.rs index 53c2a465a..a01314375 100644 --- a/pallets/parachain-staking/src/inflation.rs +++ b/pallets/parachain-staking/src/inflation.rs @@ -20,10 +20,7 @@ use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_runtime::{PerThing, Perbill, RuntimeDebug}; -use substrate_fixed::{ - transcendental::pow as floatpow, - types::{I32F32, I64F64}, -}; +use substrate_fixed::{transcendental::pow as floatpow, types::I64F64}; use crate::{ pallet::{BalanceOf, Config}, @@ -76,10 +73,10 @@ pub fn perbill_annual_to_perbill_round( annual: Range, rounds_per_year: u32, ) -> Range { - let exponent = I32F32::from_num(1) / I32F32::from_num(rounds_per_year); + let exponent = I64F64::from_num(1) / I64F64::from_num(rounds_per_year); let annual_to_round = |annual: Perbill| -> Perbill { - let x = I32F32::from_num(annual.deconstruct()) / I32F32::from_num(Perbill::ACCURACY); - let y: I64F64 = floatpow(I32F32::from_num(1) + x, exponent) + let x = I64F64::from_num(annual.deconstruct()) / I64F64::from_num(Perbill::ACCURACY); + let y: I64F64 = floatpow(I64F64::from_num(1) + x, exponent) .expect("Cannot overflow since rounds_per_year is u32 so worst case 0; QED"); Perbill::from_parts( ((y - I64F64::from_num(1)) * I64F64::from_num(Perbill::ACCURACY)) @@ -208,4 +205,19 @@ mod tests { mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 8766)) ); } + + #[test] + fn inflation_does_not_panic_at_round_number_limit() { + let schedule = Range { + min: Perbill::from_percent(100), + ideal: Perbill::from_percent(100), + max: Perbill::from_percent(100), + }; + mock_round_issuance_range(u32::MAX.into(), mock_annual_to_round(schedule, u32::MAX)); + mock_round_issuance_range(u64::MAX.into(), mock_annual_to_round(schedule, u32::MAX)); + mock_round_issuance_range(u128::MAX.into(), mock_annual_to_round(schedule, u32::MAX)); + mock_round_issuance_range(u32::MAX.into(), mock_annual_to_round(schedule, 1)); + mock_round_issuance_range(u64::MAX.into(), mock_annual_to_round(schedule, 1)); + mock_round_issuance_range(u128::MAX.into(), mock_annual_to_round(schedule, 1)); + } } diff --git a/pallets/parachain-staking/src/lib.rs b/pallets/parachain-staking/src/lib.rs index 3504f24f7..41a0e3cc0 100755 --- a/pallets/parachain-staking/src/lib.rs +++ b/pallets/parachain-staking/src/lib.rs @@ -131,9 +131,6 @@ pub mod pallet { /// Minimum number of blocks per round #[pallet::constant] type MinBlocksPerRound: Get; - /// Default number of blocks per round at genesis - #[pallet::constant] - type DefaultBlocksPerRound: Get; /// Number of rounds that candidates remain bonded before exit request is executable #[pallet::constant] type LeaveCandidatesDelay: Get; @@ -164,12 +161,6 @@ pub mod pallet { /// Maximum delegations per delegator #[pallet::constant] type MaxDelegationsPerDelegator: Get; - /// Default commission due to collators, is `CollatorCommission` storage value in genesis - #[pallet::constant] - type DefaultCollatorCommission: Get; - /// Default percent of inflation set aside for parachain bond account - #[pallet::constant] - type DefaultParachainBondReservePercent: Get; /// Minimum stake required for any candidate to be in `SelectedCandidates` for the round #[pallet::constant] type MinCollatorStk: Get>; @@ -591,18 +582,41 @@ pub mod pallet { >; #[pallet::genesis_config] - #[derive(frame_support::DefaultNoBound)] pub struct GenesisConfig { + /// Initialize balance and register all as collators: `(collator AccountId, balance + /// Amount)` pub candidates: Vec<(AccountIdOf, BalanceOf)>, - /// Vec of tuples of the format (delegator AccountId, collator AccountId, delegation - /// Amount) + /// Initialize balance and make delegations: + /// `(delegator AccountId, collator AccountId, delegation Amount, auto-compounding + /// Percent)` pub delegations: Vec<(AccountIdOf, AccountIdOf, BalanceOf)>, + /// Inflation configuration pub inflation_config: InflationInfo>, + /// Default fixed percent a collator takes off the top of due rewards + pub collator_commission: Perbill, + /// Default percent of inflation set aside for parachain bond every round + pub parachain_bond_reserve_percent: Percent, + /// Default number of blocks in a round + pub blocks_per_round: u32, + } + + impl Default for GenesisConfig { + fn default() -> Self { + Self { + candidates: vec![], + delegations: vec![], + inflation_config: Default::default(), + collator_commission: Default::default(), + parachain_bond_reserve_percent: Default::default(), + blocks_per_round: 1u32, + } + } } #[pallet::genesis_build] impl BuildGenesisConfig for GenesisConfig { fn build(&self) { + assert!(self.blocks_per_round > 0, "Blocks per round must be > 0"); >::put(self.inflation_config.clone()); let mut candidate_count = 0u32; // Initialize the candidates @@ -656,7 +670,7 @@ pub mod pallet { } } // Set collator commission to default config - >::put(T::DefaultCollatorCommission::get()); + >::put(self.collator_commission); // Set parachain bond config to default config >::put(ParachainBondConfig { // must be set soon; if not => due inflation will be sent to collators/delegators @@ -664,7 +678,7 @@ pub mod pallet { &mut sp_runtime::traits::TrailingZeroInput::zeroes(), ) .expect("infinite length input; no invalid inputs for type; qed"), - percent: T::DefaultParachainBondReservePercent::get(), + percent: self.parachain_bond_reserve_percent, payment_in_round: T::PaymentInRound::get(), }); // Set total selected candidates to minimum config @@ -673,7 +687,7 @@ pub mod pallet { let (v_count, _, total_staked) = >::select_top_candidates(1u32); // Start Round 1 at Block 0 let round: RoundInfo> = - RoundInfo::new(1u32, 0u32.into(), T::DefaultBlocksPerRound::get()); + RoundInfo::new(1u32, 0u32.into(), self.blocks_per_round); >::put(round); // Snapshot total stake >::insert(1u32, >::get()); @@ -1134,18 +1148,21 @@ pub mod pallet { ) } - #[pallet::call_index(18)] - #[pallet::weight(::WeightInfo::schedule_leave_delegators())] + /// DEPRECATED use batch util with schedule_revoke_delegation for all delegations /// Request to leave the set of delegators. If successful, the caller is scheduled to be /// allowed to exit via a [DelegationAction::Revoke] towards all existing delegations. /// Success forbids future delegation requests until the request is invoked or cancelled. + #[pallet::call_index(18)] + #[pallet::weight(::WeightInfo::schedule_leave_delegators())] pub fn schedule_leave_delegators(origin: OriginFor) -> DispatchResultWithPostInfo { let delegator = ensure_signed(origin)?; Self::delegator_schedule_revoke_all(delegator) } + + /// DEPRECATED use batch util with execute_delegation_request for all delegations + /// Execute the right to exit the set of delegators and revoke all ongoing delegations. #[pallet::call_index(19)] #[pallet::weight(::WeightInfo::execute_leave_delegators(*delegation_count))] - /// Execute the right to exit the set of delegators and revoke all ongoing delegations. pub fn execute_leave_delegators( origin: OriginFor, delegator: AccountIdOf, @@ -1154,10 +1171,12 @@ pub mod pallet { ensure_signed(origin)?; Self::delegator_execute_scheduled_revoke_all(delegator, delegation_count) } - #[pallet::call_index(20)] - #[pallet::weight(::WeightInfo::cancel_leave_delegators())] + + /// DEPRECATED use batch util with cancel_delegation_request for all delegations /// Cancel a pending request to exit the set of delegators. Success clears the pending exit /// request (thereby resetting the delay upon another `leave_delegators` call). + #[pallet::call_index(20)] + #[pallet::weight(::WeightInfo::cancel_leave_delegators())] pub fn cancel_leave_delegators(origin: OriginFor) -> DispatchResultWithPostInfo { let delegator = ensure_signed(origin)?; Self::delegator_cancel_scheduled_revoke_all(delegator) @@ -1710,19 +1729,21 @@ pub mod pallet { collator_count = collator_count.saturating_add(1u32); delegation_count = delegation_count.saturating_add(state.delegation_count); total = total.saturating_add(state.total_counted); - let snapshot_total = state.total_counted; - let top_rewardable_delegations = Self::get_rewardable_delegators(account); + + let CountedDelegations { uncounted_stake, rewardable_delegations } = + Self::get_rewardable_delegators(&account); + let total_counted = state.total_counted.saturating_sub(uncounted_stake); let snapshot = CollatorSnapshot { bond: state.bond, - delegations: top_rewardable_delegations, - total: state.total_counted, + delegations: rewardable_delegations, + total: total_counted, }; >::insert(now, account, snapshot); Self::deposit_event(Event::CollatorChosen { round: now, collator_account: account.clone(), - total_exposed_amount: snapshot_total, + total_exposed_amount: state.total_counted, }); } // insert canonical collator set @@ -1739,15 +1760,14 @@ pub mod pallet { /// - else, do nothing /// /// The intended bond amounts will be used while calculating rewards. - fn get_rewardable_delegators( - collator: &AccountIdOf, - ) -> Vec, BalanceOf>> { + fn get_rewardable_delegators(collator: &AccountIdOf) -> CountedDelegations { let requests = >::get(collator) .into_iter() .map(|x| (x.delegator, x.action)) .collect::>(); - >::get(collator) + let mut uncounted_stake = BalanceOf::::zero(); + let rewardable_delegations = >::get(collator) .expect("all members of CandidateQ must be candidates") .delegations .into_iter() @@ -1760,6 +1780,7 @@ pub mod pallet { revoke request", bond.owner ); + uncounted_stake = uncounted_stake.saturating_add(bond.amount); BalanceOf::::zero() }, Some(DelegationAction::Decrease(amount)) => { @@ -1768,13 +1789,15 @@ pub mod pallet { decrease request", bond.owner ); + uncounted_stake = uncounted_stake.saturating_add(*amount); bond.amount.saturating_sub(*amount) }, }; bond }) - .collect() + .collect(); + CountedDelegations { uncounted_stake, rewardable_delegations } } /// Temporary JIT migration of a single delegator's reserve -> lock. This will query diff --git a/pallets/parachain-staking/src/migrations.rs b/pallets/parachain-staking/src/migrations.rs index 21d43b070..4fbfb1bd9 100644 --- a/pallets/parachain-staking/src/migrations.rs +++ b/pallets/parachain-staking/src/migrations.rs @@ -36,7 +36,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use scale_info::prelude::string::String; use sp_runtime::{ traits::{AccountIdConversion, Saturating, Zero}, - Perbill, TryRuntimeError, + Perbill, Percent, TryRuntimeError, }; use sp_std::{convert::TryInto, vec::Vec}; @@ -53,6 +53,10 @@ use crate::{ RoundInfo, Staked, TopDelegations, TotalSelected, }; +const COLLATOR_COMMISSION: Perbill = Perbill::from_percent(10); +const PARACHAIN_BOND_RESERVE_PERCENT: Percent = Percent::from_percent(0); +const BLOCKS_PER_ROUND: u32 = 2 * 300; + /// Migration to purge staking storage bloat for `Points` and `AtStake` storage items pub struct InitGenesisMigration(PhantomData); impl OnRuntimeUpgrade for InitGenesisMigration { @@ -97,12 +101,12 @@ impl OnRuntimeUpgrade for InitGenesisMigration { } } // Set collator commission to default config - >::put(T::DefaultCollatorCommission::get()); + >::put(COLLATOR_COMMISSION); // Set parachain bond config to default config >::put(ParachainBondConfig { // must be set soon; if not => due inflation will be sent to collators/delegators account: T::PalletId::get().into_account_truncating(), - percent: T::DefaultParachainBondReservePercent::get(), + percent: PARACHAIN_BOND_RESERVE_PERCENT, payment_in_round: T::PaymentInRound::get(), }); // Set total selected candidates to minimum config @@ -111,7 +115,7 @@ impl OnRuntimeUpgrade for InitGenesisMigration { >::select_top_candidates(1u32); // Start Round 1 at Block 0 let round: RoundInfo> = - RoundInfo::new(1u32, 0u32.into(), T::DefaultBlocksPerRound::get()); + RoundInfo::new(1u32, 0u32.into(), BLOCKS_PER_ROUND); >::put(round); // Snapshot total stake >::insert(1u32, >::get()); diff --git a/pallets/parachain-staking/src/mock.rs b/pallets/parachain-staking/src/mock.rs index 45acfb13b..72235e155 100644 --- a/pallets/parachain-staking/src/mock.rs +++ b/pallets/parachain-staking/src/mock.rs @@ -106,7 +106,6 @@ impl Config for Test { type Currency = Balances; type MonetaryGovernanceOrigin = frame_system::EnsureRoot; type MinBlocksPerRound = MinBlocksPerRound; - type DefaultBlocksPerRound = DefaultBlocksPerRound; type LeaveCandidatesDelay = LeaveCandidatesDelay; type CandidateBondLessDelay = CandidateBondLessDelay; type LeaveDelegatorsDelay = LeaveDelegatorsDelay; @@ -117,8 +116,6 @@ impl Config for Test { type MaxTopDelegationsPerCandidate = MaxTopDelegationsPerCandidate; type MaxBottomDelegationsPerCandidate = MaxBottomDelegationsPerCandidate; type MaxDelegationsPerDelegator = MaxDelegationsPerDelegator; - type DefaultCollatorCommission = DefaultCollatorCommission; - type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; type MinCollatorStk = MinCollatorStk; type MinCandidateStk = MinCollatorStk; type MinDelegatorStk = MinDelegatorStk; @@ -206,6 +203,9 @@ impl ExtBuilder { candidates: self.collators, delegations: self.delegations, inflation_config: self.inflation, + collator_commission: DefaultCollatorCommission::get(), + parachain_bond_reserve_percent: DefaultParachainBondReservePercent::get(), + blocks_per_round: DefaultBlocksPerRound::get(), } .assimilate_storage(&mut t) .expect("Parachain Staking's storage can be assimilated"); diff --git a/pallets/parachain-staking/src/tests.rs b/pallets/parachain-staking/src/tests.rs index 0ed9682ff..c7b5ff82f 100644 --- a/pallets/parachain-staking/src/tests.rs +++ b/pallets/parachain-staking/src/tests.rs @@ -3490,9 +3490,9 @@ fn parachain_bond_inflation_reserve_matches_config() { selected_collators_number: 5, total_balance: 130, }, - Event::Rewarded { account: 1, rewards: 24 }, - Event::Rewarded { account: 7, rewards: 6 }, - Event::Rewarded { account: 10, rewards: 6 }, + Event::Rewarded { account: 1, rewards: 26 }, + Event::Rewarded { account: 7, rewards: 7 }, + Event::Rewarded { account: 10, rewards: 7 }, ]; expected.append(&mut new2); assert_eq_events!(expected.clone()); @@ -3522,9 +3522,9 @@ fn parachain_bond_inflation_reserve_matches_config() { selected_collators_number: 5, total_balance: 130, }, - Event::Rewarded { account: 1, rewards: 20 }, - Event::Rewarded { account: 7, rewards: 4 }, - Event::Rewarded { account: 10, rewards: 4 }, + Event::Rewarded { account: 1, rewards: 21 }, + Event::Rewarded { account: 7, rewards: 5 }, + Event::Rewarded { account: 10, rewards: 5 }, ]; expected.append(&mut new3); assert_eq_events!(expected.clone()); @@ -3533,7 +3533,7 @@ fn parachain_bond_inflation_reserve_matches_config() { roll_to(40); // no more paying 6 let mut new4 = vec![ - Event::ReservedForParachainBond { account: 11, value: 31 }, + Event::ReservedForParachainBond { account: 11, value: 32 }, Event::CollatorChosen { round: 9, collator_account: 1, total_exposed_amount: 40 }, Event::CollatorChosen { round: 9, collator_account: 2, total_exposed_amount: 40 }, Event::CollatorChosen { round: 9, collator_account: 3, total_exposed_amount: 20 }, @@ -3551,7 +3551,7 @@ fn parachain_bond_inflation_reserve_matches_config() { ]; expected.append(&mut new4); assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 126); + assert_eq!(Balances::free_balance(&11), 127); set_author(8, 1, 100); assert_ok!(ParachainStaking::delegate(RuntimeOrigin::signed(8), 1, 10, 10, 10)); roll_to(45); @@ -3581,7 +3581,7 @@ fn parachain_bond_inflation_reserve_matches_config() { ]; expected.append(&mut new5); assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 159); + assert_eq!(Balances::free_balance(&11), 160); set_author(9, 1, 100); set_author(10, 1, 100); roll_to(50); @@ -3605,11 +3605,11 @@ fn parachain_bond_inflation_reserve_matches_config() { ]; expected.append(&mut new6); assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 194); + assert_eq!(Balances::free_balance(&11), 195); roll_to(55); // new delegation is rewarded, 2 rounds after joining (`RewardPaymentDelay` is 2) let mut new7 = vec![ - Event::ReservedForParachainBond { account: 11, value: 36 }, + Event::ReservedForParachainBond { account: 11, value: 37 }, Event::CollatorChosen { round: 12, collator_account: 1, total_exposed_amount: 50 }, Event::CollatorChosen { round: 12, collator_account: 2, total_exposed_amount: 40 }, Event::CollatorChosen { round: 12, collator_account: 3, total_exposed_amount: 20 }, @@ -3628,7 +3628,7 @@ fn parachain_bond_inflation_reserve_matches_config() { ]; expected.append(&mut new7); assert_eq_events!(expected); - assert_eq!(Balances::free_balance(&11), 230); + assert_eq!(Balances::free_balance(&11), 232); }); } @@ -4407,9 +4407,9 @@ fn payouts_follow_delegation_changes() { selected_collators_number: 5, total_balance: 130, }, - Event::Rewarded { account: 1, rewards: 30 }, - Event::Rewarded { account: 7, rewards: 9 }, - Event::Rewarded { account: 10, rewards: 9 }, + Event::Rewarded { account: 1, rewards: 35 }, + Event::Rewarded { account: 7, rewards: 11 }, + Event::Rewarded { account: 10, rewards: 11 }, Event::CollatorChosen { round: 8, collator_account: 1, total_exposed_amount: 40 }, Event::CollatorChosen { round: 8, collator_account: 2, total_exposed_amount: 40 }, Event::CollatorChosen { round: 8, collator_account: 3, total_exposed_amount: 20 }, @@ -4421,9 +4421,9 @@ fn payouts_follow_delegation_changes() { selected_collators_number: 5, total_balance: 130, }, - Event::Rewarded { account: 1, rewards: 31 }, - Event::Rewarded { account: 7, rewards: 10 }, - Event::Rewarded { account: 10, rewards: 10 }, + Event::Rewarded { account: 1, rewards: 36 }, + Event::Rewarded { account: 7, rewards: 12 }, + Event::Rewarded { account: 10, rewards: 12 }, ]; expected.append(&mut new3); assert_eq_events!(expected.clone()); @@ -4443,8 +4443,8 @@ fn payouts_follow_delegation_changes() { total_balance: 130, }, Event::Rewarded { account: 1, rewards: 38 }, - Event::Rewarded { account: 7, rewards: 12 }, - Event::Rewarded { account: 10, rewards: 12 }, + Event::Rewarded { account: 7, rewards: 13 }, + Event::Rewarded { account: 10, rewards: 13 }, ]; expected.append(&mut new4); assert_eq_events!(expected.clone()); @@ -4470,7 +4470,7 @@ fn payouts_follow_delegation_changes() { selected_collators_number: 5, total_balance: 140, }, - Event::Rewarded { account: 1, rewards: 39 }, + Event::Rewarded { account: 1, rewards: 40 }, Event::Rewarded { account: 7, rewards: 13 }, Event::Rewarded { account: 10, rewards: 13 }, ]; @@ -4491,7 +4491,7 @@ fn payouts_follow_delegation_changes() { selected_collators_number: 5, total_balance: 140, }, - Event::Rewarded { account: 1, rewards: 41 }, + Event::Rewarded { account: 1, rewards: 42 }, Event::Rewarded { account: 7, rewards: 14 }, Event::Rewarded { account: 10, rewards: 14 }, ]; @@ -4512,7 +4512,7 @@ fn payouts_follow_delegation_changes() { selected_collators_number: 5, total_balance: 140, }, - Event::Rewarded { account: 1, rewards: 38 }, + Event::Rewarded { account: 1, rewards: 39 }, Event::Rewarded { account: 7, rewards: 12 }, Event::Rewarded { account: 10, rewards: 12 }, Event::Rewarded { account: 8, rewards: 12 }, @@ -5586,7 +5586,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_for_previous_rounds_but_not_f roll_to_round_begin(4); assert_eq_last_events!( - vec![Event::::Rewarded { account: 1, rewards: 4 }], + vec![Event::::Rewarded { account: 1, rewards: 5 }], "delegator was rewarded unexpectedly" ); let collator_snapshot = AtStake::::get(Round::::get().current, 1); @@ -5596,7 +5596,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_for_previous_rounds_but_not_f "collator snapshot's delegator count was reduced unexpectedly" ); assert_eq!( - 30, collator_snapshot.total, + 20, collator_snapshot.total, "collator snapshot's total was reduced unexpectedly", ); }); @@ -5632,7 +5632,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_when_request_cancelled() { roll_to_round_begin(4); assert_eq_last_events!( - vec![Event::::Rewarded { account: 1, rewards: 4 }], + vec![Event::::Rewarded { account: 1, rewards: 5 }], "delegator was rewarded unexpectedly", ); let collator_snapshot = AtStake::::get(Round::::get().current, 1); @@ -5699,7 +5699,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_for_previous_rounds_bu roll_to_round_begin(4); assert_eq_last_events!( vec![ - Event::::Rewarded { account: 1, rewards: 3 }, + Event::::Rewarded { account: 1, rewards: 4 }, Event::::Rewarded { account: 2, rewards: 1 }, ], "delegator was rewarded unexpectedly" @@ -5711,7 +5711,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_for_previous_rounds_bu "collator snapshot's delegator count was reduced unexpectedly" ); assert_eq!( - 40, collator_snapshot.total, + 30, collator_snapshot.total, "collator snapshot's total was reduced unexpectedly", ); }); @@ -5752,7 +5752,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_when_request_cancelled roll_to_round_begin(4); assert_eq_last_events!( vec![ - Event::::Rewarded { account: 1, rewards: 3 }, + Event::::Rewarded { account: 1, rewards: 4 }, Event::::Rewarded { account: 2, rewards: 1 }, ], "delegator was rewarded unexpectedly", @@ -5814,7 +5814,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_for_previous_rounds_but_not_fo roll_to_round_begin(4); assert_eq_last_events!( - vec![Event::::Rewarded { account: 1, rewards: 4 },], + vec![Event::::Rewarded { account: 1, rewards: 5 },], "delegator was rewarded unexpectedly" ); let collator_snapshot = AtStake::::get(Round::::get().current, 1); @@ -5824,7 +5824,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_for_previous_rounds_but_not_fo "collator snapshot's delegator count was reduced unexpectedly" ); assert_eq!( - 30, collator_snapshot.total, + 20, collator_snapshot.total, "collator snapshot's total was reduced unexpectedly", ); }); @@ -5859,7 +5859,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_when_request_cancelled() { roll_to_round_begin(4); assert_eq_last_events!( - vec![Event::::Rewarded { account: 1, rewards: 4 },], + vec![Event::::Rewarded { account: 1, rewards: 5 },], "delegator was rewarded unexpectedly", ); let collator_snapshot = AtStake::::get(Round::::get().current, 1); diff --git a/pallets/parachain-staking/src/types.rs b/pallets/parachain-staking/src/types.rs index e7b933f57..c8c2b1802 100644 --- a/pallets/parachain-staking/src/types.rs +++ b/pallets/parachain-staking/src/types.rs @@ -34,6 +34,11 @@ use crate::{ COLLATOR_LOCK_ID, DELEGATOR_LOCK_ID, }; +pub struct CountedDelegations { + pub uncounted_stake: BalanceOf, + pub rewardable_delegations: Vec>>, +} + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct Bond { pub owner: AccountId, diff --git a/pallets/slp/src/mocks/mock.rs b/pallets/slp/src/mocks/mock.rs index 4495ad6be..47a728994 100644 --- a/pallets/slp/src/mocks/mock.rs +++ b/pallets/slp/src/mocks/mock.rs @@ -41,10 +41,9 @@ use frame_system::{EnsureRoot, EnsureSignedBy}; use orml_traits::{location::RelativeReserveProvider, parameter_type_with_key}; use parity_scale_codec::{Decode, Encode}; use sp_core::{bounded::BoundedVec, hashing::blake2_256, ConstU32}; -pub use sp_runtime::Perbill; use sp_runtime::{ traits::{AccountIdConversion, Convert, IdentityLookup, TrailingZeroInput}, - AccountId32, BuildStorage, Percent, + AccountId32, BuildStorage, }; use sp_std::{boxed::Box, vec::Vec}; use xcm::v3::{prelude::*, MultiLocation, Weight}; @@ -216,7 +215,6 @@ impl bifrost_vtoken_minting::Config for Runtime { parameter_types! { pub const MinBlocksPerRound: u32 = 3; - pub const DefaultBlocksPerRound: u32 = 5; pub const LeaveCandidatesDelay: u32 = 2; pub const CandidateBondLessDelay: u32 = 2; pub const LeaveDelegatorsDelay: u32 = 2; @@ -227,8 +225,6 @@ parameter_types! { pub const MaxTopDelegationsPerCandidate: u32 = 4; pub const MaxBottomDelegationsPerCandidate: u32 = 4; pub const MaxDelegationsPerDelegator: u32 = 4; - pub const DefaultCollatorCommission: Perbill = Perbill::from_percent(20); - pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(30); pub const MinCollatorStk: u128 = 10; pub const MinDelegatorStk: u128 = 5; pub const MinDelegation: u128 = 3; @@ -242,7 +238,6 @@ impl bifrost_parachain_staking::Config for Runtime { type Currency = Balances; type MonetaryGovernanceOrigin = frame_system::EnsureRoot; type MinBlocksPerRound = MinBlocksPerRound; - type DefaultBlocksPerRound = DefaultBlocksPerRound; type LeaveCandidatesDelay = LeaveCandidatesDelay; type CandidateBondLessDelay = CandidateBondLessDelay; type LeaveDelegatorsDelay = LeaveDelegatorsDelay; @@ -253,8 +248,6 @@ impl bifrost_parachain_staking::Config for Runtime { type MaxTopDelegationsPerCandidate = MaxTopDelegationsPerCandidate; type MaxBottomDelegationsPerCandidate = MaxBottomDelegationsPerCandidate; type MaxDelegationsPerDelegator = MaxDelegationsPerDelegator; - type DefaultCollatorCommission = DefaultCollatorCommission; - type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; type MinCollatorStk = MinCollatorStk; type MinCandidateStk = MinCollatorStk; type MinDelegatorStk = MinDelegatorStk; diff --git a/pallets/slp/src/mocks/mock_kusama.rs b/pallets/slp/src/mocks/mock_kusama.rs index adb01aa24..141e0c1b8 100644 --- a/pallets/slp/src/mocks/mock_kusama.rs +++ b/pallets/slp/src/mocks/mock_kusama.rs @@ -43,10 +43,9 @@ use hex_literal::hex; use orml_traits::{location::RelativeReserveProvider, parameter_type_with_key}; use parity_scale_codec::{Decode, Encode}; use sp_core::{bounded::BoundedVec, hashing::blake2_256}; -pub use sp_runtime::Perbill; use sp_runtime::{ traits::{AccountIdConversion, Convert, TrailingZeroInput}, - AccountId32, BuildStorage, Percent, + AccountId32, BuildStorage, }; use sp_std::{boxed::Box, vec::Vec}; use xcm::v3::{prelude::*, Weight}; @@ -272,7 +271,6 @@ impl bifrost_vtoken_minting::Config for Runtime { parameter_types! { pub const MinBlocksPerRound: u32 = 3; - pub const DefaultBlocksPerRound: u32 = 5; pub const LeaveCandidatesDelay: u32 = 2; pub const CandidateBondLessDelay: u32 = 2; pub const LeaveDelegatorsDelay: u32 = 2; @@ -283,8 +281,6 @@ parameter_types! { pub const MaxTopDelegationsPerCandidate: u32 = 4; pub const MaxBottomDelegationsPerCandidate: u32 = 4; pub const MaxDelegationsPerDelegator: u32 = 4; - pub const DefaultCollatorCommission: Perbill = Perbill::from_percent(20); - pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(30); pub const MinCollatorStk: u128 = 10; pub const MinDelegatorStk: u128 = 5; pub const MinDelegation: u128 = 3; @@ -298,7 +294,6 @@ impl bifrost_parachain_staking::Config for Runtime { type Currency = Balances; type MonetaryGovernanceOrigin = frame_system::EnsureRoot; type MinBlocksPerRound = MinBlocksPerRound; - type DefaultBlocksPerRound = DefaultBlocksPerRound; type LeaveCandidatesDelay = LeaveCandidatesDelay; type CandidateBondLessDelay = CandidateBondLessDelay; type LeaveDelegatorsDelay = LeaveDelegatorsDelay; @@ -309,8 +304,6 @@ impl bifrost_parachain_staking::Config for Runtime { type MaxTopDelegationsPerCandidate = MaxTopDelegationsPerCandidate; type MaxBottomDelegationsPerCandidate = MaxBottomDelegationsPerCandidate; type MaxDelegationsPerDelegator = MaxDelegationsPerDelegator; - type DefaultCollatorCommission = DefaultCollatorCommission; - type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; type MinCollatorStk = MinCollatorStk; type MinCandidateStk = MinCollatorStk; type MinDelegatorStk = MinDelegatorStk; diff --git a/runtime/bifrost-kusama/src/lib.rs b/runtime/bifrost-kusama/src/lib.rs index b25e34213..d697fe916 100644 --- a/runtime/bifrost-kusama/src/lib.rs +++ b/runtime/bifrost-kusama/src/lib.rs @@ -878,8 +878,6 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// Minimum round length is 2 minutes (10 * 12 second block times) pub const MinBlocksPerRound: u32 = 10; - /// Blocks per round - pub const DefaultBlocksPerRound: u32 = prod_or_fast!(2 * HOURS, 10); /// Rounds before the collator leaving the candidates request can be executed pub const LeaveCandidatesDelay: u32 = 84; /// Rounds before the candidate bond increase/decrease can be executed @@ -900,10 +898,6 @@ parameter_types! { pub const MaxBottomDelegationsPerCandidate: u32 = 50; /// Maximum delegations per delegator pub const MaxDelegationsPerDelegator: u32 = 100; - /// Default fixed percent a collator takes off the top of due rewards - pub const DefaultCollatorCommission: Perbill = Perbill::from_percent(10); - /// Default percent of inflation set aside for parachain bond every round - pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(0); /// Minimum stake required to become a collator pub MinCollatorStk: u128 = 5000 * BNCS; /// Minimum stake required to be reserved to be a candidate @@ -928,7 +922,6 @@ impl bifrost_parachain_staking::Config for Runtime { type Currency = Balances; type MonetaryGovernanceOrigin = TechAdminOrCouncil; type MinBlocksPerRound = MinBlocksPerRound; - type DefaultBlocksPerRound = DefaultBlocksPerRound; type LeaveCandidatesDelay = LeaveCandidatesDelay; type CandidateBondLessDelay = CandidateBondLessDelay; type LeaveDelegatorsDelay = LeaveDelegatorsDelay; @@ -939,8 +932,6 @@ impl bifrost_parachain_staking::Config for Runtime { type MaxTopDelegationsPerCandidate = MaxTopDelegationsPerCandidate; type MaxBottomDelegationsPerCandidate = MaxBottomDelegationsPerCandidate; type MaxDelegationsPerDelegator = MaxDelegationsPerDelegator; - type DefaultCollatorCommission = DefaultCollatorCommission; - type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; type MinCollatorStk = MinCollatorStk; type MinCandidateStk = MinCandidateStk; type MinDelegation = MinDelegatorStk;