From 50852e23a74351ca98188350609da0c073faab14 Mon Sep 17 00:00:00 2001 From: PraetorP Date: Wed, 31 Aug 2022 14:08:40 +0000 Subject: [PATCH] minimal deposit for staking increased to 100 , added impl for `payout_stakers`. --- --- a/pallets/app-promotion/src/benchmarking.rs +++ b/pallets/app-promotion/src/benchmarking.rs @@ -36,7 +36,8 @@ benchmarks! { where_clause{ where T: Config + pallet_unique::Config + pallet_evm_migration::Config , - T::BlockNumber: From + T::BlockNumber: From + Into, + <::Currency as Currency>::Balance: Sum + From } start_app_promotion { @@ -73,16 +74,16 @@ let _ = ::Currency::make_free_balance_be(&caller, Perbill::from_rational(1u32, 2) * BalanceOf::::max_value()); let _ = PromototionPallet::::stake(RawOrigin::Signed(caller.clone()).into(), share * ::Currency::total_balance(&caller))?; - } : {PromototionPallet::::unstake(RawOrigin::Signed(caller.clone()).into(), share * ::Currency::total_balance(&caller))?} + } : {PromototionPallet::::unstake(RawOrigin::Signed(caller.clone()).into())?} - recalculate_stake { - let caller = account::("caller", 0, SEED); - let share = Perbill::from_rational(1u32, 10); - let _ = ::Currency::make_free_balance_be(&caller, Perbill::from_rational(1u32, 2) * BalanceOf::::max_value()); - let _ = PromototionPallet::::stake(RawOrigin::Signed(caller.clone()).into(), share * ::Currency::total_balance(&caller))?; - let block = ::current_block_number(); - let mut acc = >::default(); - } : {PromototionPallet::::recalculate_stake(&caller, block, share * ::Currency::total_balance(&caller), &mut acc)} + // recalculate_and_insert_stake{ + // let caller = account::("caller", 0, SEED); + // let share = Perbill::from_rational(1u32, 10); + // let _ = ::Currency::make_free_balance_be(&caller, Perbill::from_rational(1u32, 2) * BalanceOf::::max_value()); + // let _ = PromototionPallet::::stake(RawOrigin::Signed(caller.clone()).into(), share * ::Currency::total_balance(&caller))?; + // let block = ::current_block_number(); + // let mut acc = >::default(); + // } : {PromototionPallet::::recalculate_and_insert_stake(&caller, block, share * ::Currency::total_balance(&caller), &mut acc)} sponsor_collection { let pallet_admin = account::("admin", 0, SEED); --- a/pallets/app-promotion/src/lib.rs +++ b/pallets/app-promotion/src/lib.rs @@ -191,12 +191,12 @@ pub type NextInterestBlock = StorageValue; - /// Stores the address of the staker for which the last revenue recalculation was performed. + /// Stores hash a record for which the last revenue recalculation was performed. /// If `None`, then recalculation has not yet been performed or calculations have been completed for all stakers. #[pallet::storage] - #[pallet::getter(fn get_last_calculated_staker)] - pub type LastCalcucaltedStaker = - StorageValue; + #[pallet::getter(fn get_next_calculated_record)] + pub type NextCalculatedRecord = + StorageValue; #[pallet::hooks] impl Hooks> for Pallet { @@ -259,8 +259,8 @@ #[pallet::call] impl Pallet where - T::BlockNumber: From, - <::Currency as Currency>::Balance: Sum + From + T::BlockNumber: From + Into, + <::Currency as Currency>::Balance: Sum + From, { #[pallet::weight(T::WeightInfo::set_admin_address())] pub fn set_admin_address(origin: OriginFor, admin: T::CrossAccountId) -> DispatchResult { @@ -312,9 +312,11 @@ #[pallet::weight(T::WeightInfo::stake())] pub fn stake(staker: OriginFor, amount: BalanceOf) -> DispatchResult { let staker_id = ensure_signed(staker)?; - - ensure!(amount >= Into::>::into(100u128) * T::Nominal::get(), ArithmeticError::Underflow); + ensure!( + amount >= Into::>::into(100u128) * T::Nominal::get(), + ArithmeticError::Underflow + ); let balance = <::Currency as Currency>::free_balance(&staker_id); @@ -365,7 +367,7 @@ amount }) .sum(); - + let block = T::RelayBlockNumberProvider::current_block_number() + T::PendingInterval::get(); >::insert( @@ -374,9 +376,13 @@ .checked_add(&total_staked) .ok_or(ArithmeticError::Overflow)?, ); - - TotalStaked::::set(TotalStaked::::get().checked_sub(&total_staked).ok_or(ArithmeticError::Underflow)?); // when error we should recover stake state for the staker + TotalStaked::::set( + TotalStaked::::get() + .checked_sub(&total_staked) + .ok_or(ArithmeticError::Underflow)?, + ); // when error we should recover initial stake state for the staker + Ok(None.into()) // let staker_id = ensure_signed(staker)?; @@ -511,16 +517,64 @@ admin_id == Admin::::get().ok_or(Error::::AdminNotSet)?, Error::::NoPermission ); - - let raw_key = Staked::::hashed_key_for((admin_id, T::BlockNumber::default())); - - let key_iterator = Staked::::iter_keys_from(raw_key).skip(1).into_iter(); - - match Self::get_last_calculated_staker() { - Some(last_staker) => {}, - None => {} - }; + let current_recalc_block = + Self::get_current_recalc_block(T::RelayBlockNumberProvider::current_block_number()); + let next_recalc_block = current_recalc_block + T::RecalculationInterval::get(); + + let mut storage_iterator = Self::get_next_calculated_key() + .map_or(Staked::::iter().skip(0), |key| { + Staked::::iter_from(key).skip(1) + }); + + NextCalculatedRecord::::set(None); + + { + let mut stakers_number = stakers_number.unwrap_or(20); + let mut current_id = admin_id; + let mut income_acc = BalanceOf::::default(); + + while let Some(((id, staked_block), (amount, next_recalc_block_for_stake))) = + storage_iterator.next() + { + if current_id != id { + if income_acc != BalanceOf::::default() { + >::transfer( + &T::TreasuryAccountId::get(), + ¤t_id, + income_acc, + ExistenceRequirement::KeepAlive, + ) + .and_then(|_| Self::add_lock_balance(¤t_id, income_acc))?; + + Self::deposit_event(Event::StakingRecalculation( + current_id, amount, income_acc, + )); + } + + stakers_number -= 1; + if stakers_number == 0 { + NextCalculatedRecord::::set(Some((id, staked_block))); + break; + } + income_acc = BalanceOf::::default(); + current_id = id; + }; + if next_recalc_block_for_stake >= current_recalc_block { + Self::recalculate_and_insert_stake( + ¤t_id, + staked_block, + next_recalc_block, + amount, + ((next_recalc_block_for_stake - current_recalc_block) + / T::RecalculationInterval::get()) + .into() + 1, + &mut income_acc, + ); + } + } + } + Ok(()) } } @@ -609,31 +663,43 @@ Self::total_staked_by_id_per_block(staker.as_sub()).unwrap_or_default() } - fn recalculate_stake( + fn recalculate_and_insert_stake( staker: &T::AccountId, - block: T::BlockNumber, + staked_block: T::BlockNumber, + next_recalc_block: T::BlockNumber, base: BalanceOf, + iters: u32, income_acc: &mut BalanceOf, ) { - let income = Self::calculate_income(base); - // base.checked_add(&income).map(|res| { - // >::insert((staker, block), res); - // *income_acc += income; - // >::transfer( - // &T::TreasuryAccountId::get(), - // staker, - // income, - // ExistenceRequirement::KeepAlive, - // ) - // .and_then(|_| Self::add_lock_balance(staker, income)); - // }); + let income = Self::calculate_income(base, iters); + + base.checked_add(&income).map(|res| { + >::insert((staker, staked_block), (res, next_recalc_block)); + *income_acc += income; + }); } - fn calculate_income(base: I) -> I + fn calculate_income(base: I, iters: u32) -> I where I: EncodeLike> + Balance, { - T::IntervalIncome::get() * base + let mut income = base; + + (0..iters).for_each(|_| income += T::IntervalIncome::get() * income); + + income - base + } + + fn get_current_recalc_block(current_relay_block: T::BlockNumber) -> T::BlockNumber { + (current_relay_block / T::RecalculationInterval::get()) * T::RecalculationInterval::get() + } + + // fn get_next_recalc_block(current_relay_block: T::BlockNumber) -> T::BlockNumber { + // Self::get_current_recalc_block(current_relay_block) + T::RecalculationInterval::get() + // } + + fn get_next_calculated_key() -> Option> { + Self::get_next_calculated_record().map(|key| Staked::::hashed_key_for(key)) } } --- a/pallets/app-promotion/src/weights.rs +++ b/pallets/app-promotion/src/weights.rs @@ -3,7 +3,7 @@ //! Autogenerated weights for pallet_app_promotion //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-08-30, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2022-08-31, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 // Executed Command: @@ -26,6 +26,7 @@ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(missing_docs)] #![allow(clippy::unnecessary_cast)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; @@ -39,7 +40,6 @@ fn payout_stakers() -> Weight; fn stake() -> Weight; fn unstake() -> Weight; - fn recalculate_stake() -> Weight; fn sponsor_collection() -> Weight; fn stop_sponsoring_collection() -> Weight; fn sponsor_contract() -> Weight; @@ -53,71 +53,75 @@ // Storage: ParachainSystem ValidationData (r:1 w:0) // Storage: Promotion NextInterestBlock (r:0 w:1) fn start_app_promotion() -> Weight { - (2_299_000 as Weight) + (3_995_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: Promotion StartBlock (r:1 w:1) // Storage: Promotion NextInterestBlock (r:0 w:1) fn stop_app_promotion() -> Weight { - (1_733_000 as Weight) + (3_623_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: Promotion Admin (r:0 w:1) fn set_admin_address() -> Weight { - (553_000 as Weight) + (1_203_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Promotion Admin (r:1 w:0) + // Storage: ParachainSystem ValidationData (r:1 w:0) + // Storage: Promotion NextCalculatedRecord (r:1 w:1) + // Storage: Promotion Staked (r:2 w:0) fn payout_stakers() -> Weight { - (1_398_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) + (10_859_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: System Account (r:1 w:1) // Storage: Balances Locks (r:1 w:1) // Storage: ParachainSystem ValidationData (r:1 w:0) // Storage: Promotion Staked (r:1 w:1) + // Storage: Promotion TotalStaked (r:1 w:1) fn stake() -> Weight { - (9_506_000 as Weight) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) + (14_789_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) } - // Storage: System Account (r:1 w:0) + // Storage: Promotion Staked (r:2 w:1) + // Storage: ParachainSystem ValidationData (r:1 w:0) + // Storage: Promotion PendingUnstake (r:1 w:1) + // Storage: Promotion TotalStaked (r:1 w:1) fn unstake() -> Weight { - (2_529_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - } - // Storage: System Account (r:1 w:0) - fn recalculate_stake() -> Weight { - (2_203_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) + (16_889_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) } // Storage: Promotion Admin (r:1 w:0) // Storage: Common CollectionById (r:1 w:1) fn sponsor_collection() -> Weight { - (10_882_000 as Weight) + (18_377_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Promotion Admin (r:1 w:0) // Storage: Common CollectionById (r:1 w:1) fn stop_sponsoring_collection() -> Weight { - (10_544_000 as Weight) + (13_989_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Promotion Admin (r:1 w:0) // Storage: EvmContractHelpers Sponsoring (r:0 w:1) fn sponsor_contract() -> Weight { - (2_163_000 as Weight) + (4_162_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Promotion Admin (r:1 w:0) // Storage: EvmContractHelpers Sponsoring (r:1 w:1) fn stop_sponsoring_contract() -> Weight { - (3_511_000 as Weight) + (5_457_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -129,71 +133,75 @@ // Storage: ParachainSystem ValidationData (r:1 w:0) // Storage: Promotion NextInterestBlock (r:0 w:1) fn start_app_promotion() -> Weight { - (2_299_000 as Weight) + (3_995_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } // Storage: Promotion StartBlock (r:1 w:1) // Storage: Promotion NextInterestBlock (r:0 w:1) fn stop_app_promotion() -> Weight { - (1_733_000 as Weight) + (3_623_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } // Storage: Promotion Admin (r:0 w:1) fn set_admin_address() -> Weight { - (553_000 as Weight) + (1_203_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Promotion Admin (r:1 w:0) + // Storage: ParachainSystem ValidationData (r:1 w:0) + // Storage: Promotion NextCalculatedRecord (r:1 w:1) + // Storage: Promotion Staked (r:2 w:0) fn payout_stakers() -> Weight { - (1_398_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + (10_859_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: System Account (r:1 w:1) // Storage: Balances Locks (r:1 w:1) // Storage: ParachainSystem ValidationData (r:1 w:0) // Storage: Promotion Staked (r:1 w:1) + // Storage: Promotion TotalStaked (r:1 w:1) fn stake() -> Weight { - (9_506_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + (14_789_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } - // Storage: System Account (r:1 w:0) + // Storage: Promotion Staked (r:2 w:1) + // Storage: ParachainSystem ValidationData (r:1 w:0) + // Storage: Promotion PendingUnstake (r:1 w:1) + // Storage: Promotion TotalStaked (r:1 w:1) fn unstake() -> Weight { - (2_529_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) - } - // Storage: System Account (r:1 w:0) - fn recalculate_stake() -> Weight { - (2_203_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + (16_889_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } // Storage: Promotion Admin (r:1 w:0) // Storage: Common CollectionById (r:1 w:1) fn sponsor_collection() -> Weight { - (10_882_000 as Weight) + (18_377_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Promotion Admin (r:1 w:0) // Storage: Common CollectionById (r:1 w:1) fn stop_sponsoring_collection() -> Weight { - (10_544_000 as Weight) + (13_989_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Promotion Admin (r:1 w:0) // Storage: EvmContractHelpers Sponsoring (r:0 w:1) fn sponsor_contract() -> Weight { - (2_163_000 as Weight) + (4_162_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Promotion Admin (r:1 w:0) // Storage: EvmContractHelpers Sponsoring (r:1 w:1) fn stop_sponsoring_contract() -> Weight { - (3_511_000 as Weight) + (5_457_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } -- gitstuff