diff --git a/Cargo.lock b/Cargo.lock index a335d0fb..b4b846a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,6 +1026,7 @@ dependencies = [ "pallet-scheduler-credit", "pallet-session", "pallet-sminer", + "pallet-sminer-reward", "pallet-storage-handler", "pallet-sudo", "pallet-tee-worker", @@ -5836,6 +5837,7 @@ dependencies = [ "pallet-scheduler-credit", "pallet-session", "pallet-sminer", + "pallet-sminer-reward", "pallet-storage-handler", "pallet-tee-worker", "pallet-timestamp", @@ -6518,6 +6520,7 @@ dependencies = [ "pallet-cess-staking", "pallet-preimage", "pallet-scheduler", + "pallet-sminer-reward", "pallet-storage-handler", "pallet-tee-worker", "pallet-timestamp", @@ -6531,6 +6534,18 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-sminer-reward" +version = "0.7.4" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-staking-reward-curve" version = "4.0.0-dev" @@ -6552,6 +6567,7 @@ dependencies = [ "frame-system", "log", "pallet-balances", + "pallet-sminer-reward", "parity-scale-codec", "scale-info", "serde", diff --git a/c-pallets/audit/Cargo.toml b/c-pallets/audit/Cargo.toml index 83a54f4d..f0128246 100644 --- a/c-pallets/audit/Cargo.toml +++ b/c-pallets/audit/Cargo.toml @@ -23,6 +23,7 @@ cp-bloom-filter = { path = '../../primitives/bloom-filter', version = '0.1.0', d cp-scheduler-credit = { path = '../../primitives/scheduler-credit', version = '0.1.0', default-features = false } cp-cess-common = { path = '../../primitives/common', version = '0.1.0', default-features = false } cp-enclave-verify = { path = '../../primitives/enclave-verify', version = '0.1.0', default-features = false } +pallet-sminer-reward = { default-features = false, path = "../sminer-reward", version = "0.7.4" } [dependencies.frame-benchmarking] default-features = false @@ -148,6 +149,7 @@ std = [ "pallet-tee-worker/std", "cp-cess-common/std", "cp-cess-common/std", + "pallet-sminer-reward/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/c-pallets/file-bank/src/lib.rs b/c-pallets/file-bank/src/lib.rs index 88eef4cc..e91ca7ec 100755 --- a/c-pallets/file-bank/src/lib.rs +++ b/c-pallets/file-bank/src/lib.rs @@ -860,7 +860,7 @@ pub mod pallet { ensure!(Self::check_permission(sender.clone(), owner.clone()), Error::::NoPermission); ensure!(>::contains_key(&owner, &name), Error::::NonExistent); let bucket = >::try_get(&owner, &name).map_err(|_| Error::::Unexpected)?; - ensure!(bucket.object_list == 0, Error::::NotEmpty); + ensure!(bucket.object_list.len() == 0, Error::::NotEmpty); >::remove(&owner, &name); >::try_mutate(&owner, |bucket_list| -> DispatchResult { diff --git a/c-pallets/sminer-reward/Cargo.toml b/c-pallets/sminer-reward/Cargo.toml new file mode 100644 index 00000000..1e8598f8 --- /dev/null +++ b/c-pallets/sminer-reward/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "pallet-sminer-reward" +authors = ["CESS LAB"] +version = "0.7.4" +edition = "2021" +license = "Apache-2.0" +repository = "https://github.com/CESSProject/cess" +description = "FRAME pallet for sminer management" +readme = "README.md" + +[dependencies] +scale-info = { default-features = false, features = ['derive'], version = "2.0.1" } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } + +#substrate pallet +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/CESSProject/substrate", branch = "cess-polkadot-v0.9.42" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/CESSProject/substrate", branch = "cess-polkadot-v0.9.42" } +sp-std = { version = "5.0.0", git = 'https://github.com/CESSProject/substrate', branch = "cess-polkadot-v0.9.42", default-features = false } +sp-runtime = { version = "7.0.0", git = 'https://github.com/CESSProject/substrate', branch = "cess-polkadot-v0.9.42", default-features = false } + + +[features] +default = ["std"] +std = [ + "codec/std", + "scale-info/std", + "frame-support/std", + "frame-system/std", + "sp-std/std", + "sp-runtime/std", +] \ No newline at end of file diff --git a/c-pallets/sminer-reward/src/lib.rs b/c-pallets/sminer-reward/src/lib.rs new file mode 100644 index 00000000..92bae8a3 --- /dev/null +++ b/c-pallets/sminer-reward/src/lib.rs @@ -0,0 +1,83 @@ +#![cfg_attr(not(feature = "std"), no_std)] +use frame_support::{ + traits::{ + Currency, ReservableCurrency, + }, + dispatch::{DispatchResult}, + pallet_prelude::{StorageValue, ValueQuery}, +}; +use codec::{Decode, Encode}; +use scale_info::TypeInfo; +// use sp_std::prelude::*; +use sp_runtime::{ + SaturatedConversion, + traits::{CheckedAdd, CheckedSub}, +}; +// use frame_system::pallet_prelude::*; + +pub use pallet::*; + +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + pub struct Pallet(sp_std::marker::PhantomData); + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The currency trait. + type Currency: ReservableCurrency; + } + + #[pallet::error] + pub enum Error { + Overflow, + } + + #[pallet::storage] + #[pallet::getter(fn currency_reward)] + pub(super) type CurrencyReward = StorageValue<_, BalanceOf, ValueQuery>; +} + +pub trait RewardPool { + fn get_reward() -> Balance; + fn get_reward_128() -> u128; + fn add_reward(amount: Balance) -> DispatchResult; + fn sub_reward(amount: Balance) -> DispatchResult; +} + +impl RewardPool> for Pallet { + fn get_reward() -> BalanceOf { + >::get() + } + + fn get_reward_128() -> u128 { + >::get().saturated_into() + } + + fn add_reward(amount: BalanceOf) -> DispatchResult { + >::mutate(|v| -> DispatchResult { + // The total issuance amount will not exceed u128::Max, so there is no overflow risk + *v = v.checked_add(&amount).ok_or(Error::::Overflow)?; + + Ok(()) + })?; + + Ok(()) + } + + fn sub_reward(amount: BalanceOf) -> DispatchResult { + >::mutate(|v| -> DispatchResult { + // The total issuance amount will not exceed u128::Max, so there is no overflow risk + *v = v.checked_sub(&amount).ok_or(Error::::Overflow)?; + + Ok(()) + })?; + + Ok(()) + } +} \ No newline at end of file diff --git a/c-pallets/sminer/Cargo.toml b/c-pallets/sminer/Cargo.toml index 2d27b3a9..3bb1659d 100644 --- a/c-pallets/sminer/Cargo.toml +++ b/c-pallets/sminer/Cargo.toml @@ -25,6 +25,7 @@ pallet-cess-staking = { path = '../staking', version = '4.0.0-dev', default-feat #local crate pallet-tee-worker = { default-features = false, path = '../tee-worker', version = '0.7.0' } pallet-storage-handler = { default-features = false, path = '../storage-handler', version = '0.7.0' } +pallet-sminer-reward = { default-features = false, path = "../sminer-reward", version = "0.7.4" } [dependencies.frame-benchmarking] default-features = false @@ -112,6 +113,7 @@ std = [ "pallet-scheduler/std", "frame-benchmarking/std", "cp-cess-common/std", + "pallet-sminer-reward/std", ] runtime-benchmarks = [ diff --git a/c-pallets/sminer/src/functions.rs b/c-pallets/sminer/src/functions.rs index ef6a70e9..1cbac229 100644 --- a/c-pallets/sminer/src/functions.rs +++ b/c-pallets/sminer/src/functions.rs @@ -45,16 +45,12 @@ impl Pallet { if miner_info.collaterals > punish_amount { T::Currency::unreserve(miner, punish_amount); T::Currency::transfer(miner, &reward_pot, punish_amount, KeepAlive)?; - >::mutate(|reward| { - *reward = *reward + punish_amount; - }); + T::RewardPool::add_reward(punish_amount)?; miner_info.collaterals = miner_info.collaterals.checked_sub(&punish_amount).ok_or(Error::::Overflow)?; } else { T::Currency::unreserve(miner, miner_info.collaterals); T::Currency::transfer(miner, &reward_pot, miner_info.collaterals, KeepAlive)?; - >::mutate(|reward| { - *reward = *reward + miner_info.collaterals; - }); + T::RewardPool::add_reward(miner_info.collaterals)?; miner_info.collaterals = BalanceOf::::zero(); miner_info.debt = punish_amount.checked_sub(&miner_info.collaterals).ok_or(Error::::Overflow)?; } @@ -95,9 +91,7 @@ impl Pallet { if let Ok(reward_info) = >::try_get(acc).map_err(|_| Error::::NotExisted) { let reward = reward_info.total_reward .checked_sub(&reward_info.reward_issued).ok_or(Error::::Overflow)?; - >::mutate(|v| { - *v = *v + reward; - }); + T::RewardPool::add_reward(reward)?; } let mut miner_list = AllMiner::::get(); diff --git a/c-pallets/sminer/src/helper.rs b/c-pallets/sminer/src/helper.rs index bdac4a5b..dc031150 100644 --- a/c-pallets/sminer/src/helper.rs +++ b/c-pallets/sminer/src/helper.rs @@ -145,7 +145,7 @@ impl Pallet { miner_idle_space: u128, miner_service_space: u128, ) -> DispatchResult { - let total_reward = >::get(); + let total_reward = T::RewardPool::get_reward(); let total_power = Self::calculate_power(total_idle_space, total_service_space); let miner_power = Self::calculate_power(miner_idle_space, miner_service_space); @@ -189,11 +189,7 @@ impl Pallet { Ok(()) })?; - - >::mutate(|v| -> DispatchResult { - *v = v.checked_sub(&order.order_reward).ok_or(Error::::Overflow)?; - Ok(()) - })?; + T::RewardPool::sub_reward(order.order_reward)?; Ok(()) } @@ -240,9 +236,7 @@ impl Pallet { if let Ok(reward_info) = >::try_get(acc).map_err(|_| Error::::NotExisted) { let reward = reward_info.total_reward .checked_sub(&reward_info.reward_issued).ok_or(Error::::Overflow)?; - >::mutate(|v| { - *v = *v + reward; - }); + T::RewardPool::add_reward(reward)?; } let mut miner_list = AllMiner::::get(); miner_list.retain(|s| s != acc); diff --git a/c-pallets/sminer/src/lib.rs b/c-pallets/sminer/src/lib.rs index 4ebc6cf5..9e3fbab2 100644 --- a/c-pallets/sminer/src/lib.rs +++ b/c-pallets/sminer/src/lib.rs @@ -43,6 +43,7 @@ use cp_enclave_verify::verify_rsa; use pallet_tee_worker::TeeWorkerHandler; use cp_bloom_filter::BloomFilter; use pallet_storage_handler::StorageHandle; +use pallet_sminer_reward::RewardPool; pub use pallet::*; @@ -107,6 +108,8 @@ pub mod pallet { /// The WeightInfo. type WeightInfo: WeightInfo; + type RewardPool: RewardPool>; + type FScheduler: ScheduleNamed; type AScheduler: ScheduleAnon; @@ -246,10 +249,6 @@ pub mod pallet { pub(super) type FaucetRecordMap = StorageMap<_, Blake2_128Concat, T::AccountId, FaucetRecord>>; - #[pallet::storage] - #[pallet::getter(fn currency_reward)] - pub(super) type CurrencyReward = StorageValue<_, BalanceOf, ValueQuery>; - #[pallet::storage] #[pallet::getter(fn miner_public_key)] pub(super) type MinerPublicKey = StorageMap<_, Blake2_128Concat, [u8; 32], AccountOf>; @@ -402,16 +401,10 @@ pub mod pallet { if miner_info.debt > collaterals { miner_info.debt = miner_info.debt.checked_sub(&collaterals).ok_or(Error::::Overflow)?; remaining = BalanceOf::::zero(); - >::mutate(|reward| -> DispatchResult { - *reward = reward.checked_add(&collaterals).ok_or(Error::::Overflow)?; - Ok(()) - })?; + T::RewardPool::add_reward(collaterals)?; } else { remaining = remaining.checked_sub(&miner_info.debt).ok_or(Error::::Overflow)?; - >::mutate(|reward| -> DispatchResult { - *reward = reward.checked_add(&miner_info.debt).ok_or(Error::::Overflow)?; - Ok(()) - })?; + T::RewardPool::add_reward(miner_info.debt)?; miner_info.debt = BalanceOf::::zero(); } } @@ -746,10 +739,8 @@ impl OnUnbalanced> for Pallet { // Must resolve into existing but better to be safe. let _ = T::Currency::resolve_creating(&T::PalletId::get().into_account_truncating(), amount); - >::mutate(|v| { - // The total issuance amount will not exceed u128::Max, so there is no overflow risk - *v = *v + numeric_amount; - }); + // The total issuance amount will not exceed u128::Max, so there is no overflow risk + T::RewardPool::add_reward(numeric_amount).unwrap(); Self::deposit_event(Event::Deposit { balance: numeric_amount }); } @@ -776,7 +767,6 @@ pub trait MinerControl { fn get_miner_idle_space(acc: &AccountId) -> Result; fn get_miner_count() -> u32; - fn get_reward() -> u128; fn calculate_miner_reward( miner: &AccountId, total_idle_space: u128, @@ -919,10 +909,6 @@ impl MinerControl<::AccountId, BlockNumber >::count() } - fn get_reward() -> u128 { - >::get().saturated_into() - } - fn calculate_miner_reward( miner: &AccountOf, total_idle_space: u128, diff --git a/c-pallets/storage-handler/Cargo.toml b/c-pallets/storage-handler/Cargo.toml index 8ef520bc..ca676445 100644 --- a/c-pallets/storage-handler/Cargo.toml +++ b/c-pallets/storage-handler/Cargo.toml @@ -24,6 +24,7 @@ frame-benchmarking = { version = '4.0.0-dev', git = 'https://github.com/CESSProj # local dependencies cp-cess-common = { version = '0.1.0', path = '../../primitives/common', default-features = false } +pallet-sminer-reward = { default-features = false, path = "../sminer-reward", version = "0.7.4" } [features] default = ["std"] @@ -36,6 +37,7 @@ std = [ "sp-std/std", "sp-runtime/std", "frame-benchmarking/std", + "pallet-sminer-reward/std", ] try-runtime = [ "frame-support/try-runtime" ] diff --git a/c-pallets/storage-handler/src/lib.rs b/c-pallets/storage-handler/src/lib.rs index 6798cdfc..2dbcb1a3 100644 --- a/c-pallets/storage-handler/src/lib.rs +++ b/c-pallets/storage-handler/src/lib.rs @@ -24,6 +24,7 @@ use sp_std::{convert::TryInto, prelude::*, str}; use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use cp_cess_common::*; +use pallet_sminer_reward::RewardPool; pub mod weights; use weights::WeightInfo; @@ -65,7 +66,7 @@ pub mod pallet { type OneDay: Get>; /// pallet address. #[pallet::constant] - type FilbakPalletId: Get; + type RewardPalletId: Get; #[pallet::constant] type TreasuryPalletId: Get; @@ -75,6 +76,8 @@ pub mod pallet { #[pallet::constant] type FrozenDays: Get> + Clone + Eq + PartialEq; + + type RewardPool: RewardPool>; } #[pallet::event] @@ -190,12 +193,19 @@ pub mod pallet { let price: BalanceOf = unit_price .checked_mul(&gib_count.saturated_into()) .ok_or(Error::::Overflow)?; + + let price = price.checked_div(&2u32.saturated_into()).ok_or(Error::::Overflow)?; + ensure!( ::Currency::can_slash(&sender, price.clone()), Error::::InsufficientBalance ); - let acc = T::FilbakPalletId::get().into_account_truncating(); - ::Currency::transfer(&sender, &acc, price.clone(), KeepAlive)?; + let r_acc = T::RewardPalletId::get().into_account_truncating(); + let t_acc = T::TreasuryPalletId::get().into_account_truncating(); + + T::RewardPool::add_reward(price.into())?; + ::Currency::transfer(&sender, &r_acc, price.clone(), KeepAlive)?; + ::Currency::transfer(&sender, &t_acc, price.clone(), KeepAlive)?; Self::deposit_event(Event::::BuySpace { acc: sender, storage_capacity: space, spend: price }); Ok(()) @@ -253,14 +263,19 @@ pub mod pallet { Error::::InsufficientBalance ); - let acc: AccountOf = T::FilbakPalletId::get().into_account_truncating(); Self::add_purchased_space( space, )?; Self::expension_puchased_package(sender.clone(), space)?; - ::Currency::transfer(&sender, &acc, price.clone(), KeepAlive)?; + let r_acc = T::RewardPalletId::get().into_account_truncating(); + let t_acc = T::TreasuryPalletId::get().into_account_truncating(); + + T::RewardPool::add_reward(price.into())?; + + ::Currency::transfer(&sender, &t_acc, price.clone(), KeepAlive)?; + ::Currency::transfer(&sender, &r_acc, price.clone(), KeepAlive)?; Self::deposit_event(Event::::ExpansionSpace { acc: sender, @@ -297,12 +312,19 @@ pub mod pallet { .ok_or(Error::::Overflow)? .try_into() .map_err(|_e| Error::::Overflow)?; + ensure!( ::Currency::can_slash(&sender, price.clone()), Error::::InsufficientBalance ); - let acc = T::FilbakPalletId::get().into_account_truncating(); - ::Currency::transfer(&sender, &acc, price.clone(), KeepAlive)?; + + let r_acc = T::RewardPalletId::get().into_account_truncating(); + let t_acc = T::TreasuryPalletId::get().into_account_truncating(); + + T::RewardPool::add_reward(price.into())?; + + ::Currency::transfer(&sender, &t_acc, price.clone(), KeepAlive)?; + ::Currency::transfer(&sender, &r_acc, price.clone(), KeepAlive)?; Self::update_puchased_package(sender.clone(), days)?; Self::deposit_event(Event::::RenewalSpace { acc: sender, diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 6872486f..523b345b 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -111,6 +111,7 @@ pallet-scheduler-credit = { default-features = false, version = "0.1.0", path = # local dependencies pallet-sminer = { default-features = false, path = "../c-pallets/sminer", version = "0.7.0" } +pallet-sminer-reward = { default-features = false, path = "../c-pallets/sminer-reward", version = "0.7.4" } pallet-audit = { default-features = false, path = "../c-pallets/audit", version = "0.7.0" } pallet-file-bank = { default-features = false, path = "../c-pallets/file-bank", version = "0.7.0" } pallet-tee-worker = { default-features = false, path = "../c-pallets/tee-worker", version = "0.7.0" } @@ -166,6 +167,7 @@ std = [ "pallet-storage-handler/std", "pallet-oss/std", "pallet-cacher/std", + "pallet-sminer-reward/std", "pallet-preimage/std", "pallet-assets/std", "pallet-child-bounties/std", diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index ef6b506f..3fa20846 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -956,6 +956,11 @@ impl pallet_sminer::Config for Runtime { type SPalletsOrigin = OriginCaller; type SProposal = RuntimeCall; type StorageHandle = StorageHandler; + type RewardPool = SminerReward; +} + +impl pallet_sminer_reward::Config for Runtime { + type Currency = Balances; } parameter_types! { @@ -970,7 +975,8 @@ impl pallet_storage_handler::Config for Runtime { type Currency = Balances; type WeightInfo = pallet_storage_handler::weights::SubstrateWeight; type OneDay = OneDay; - type FilbakPalletId = RewardPalletId; + type RewardPalletId = RewardPalletId; + type RewardPool = SminerReward; type TreasuryPalletId = TreasuryPalletId; type StateStringMax = StateStringMax; type FrozenDays = FrozenDays; @@ -1549,6 +1555,7 @@ construct_runtime!( SchedulerCredit: pallet_scheduler_credit = 65, Oss: pallet_oss = 66, Cacher: pallet_cacher = 67, + SminerReward: pallet_sminer_reward = 68, } );