Skip to content

Commit

Permalink
Sync Phala pallets to f87192b64d90b06d1d8415fb47a1adffea43cc45‘
Browse files Browse the repository at this point in the history
  • Loading branch information
jasl committed May 28, 2023
1 parent 8e84358 commit c4ba598
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

7 changes: 4 additions & 3 deletions pallets/phala/src/compute/base_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ pub mod pallet {
{
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
type MigrationAccountId: Get<Self::AccountId>;
type WPhaMinBalance: Get<BalanceOf<Self>>;
}

#[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq, RuntimeDebug)]
Expand Down Expand Up @@ -1032,7 +1031,8 @@ pub mod pallet {
None => return false,
};
let current_balance = bmul(nft.shares, &price);
if current_balance > T::WPhaMinBalance::get() {
let wpha_min = wrapped_balances::Pallet::<T>::min_balance();
if current_balance > wpha_min {
return false;
}
pool_info.total_shares -= nft.shares;
Expand Down Expand Up @@ -1068,7 +1068,8 @@ pub mod pallet {
None => return,
};

while pool_info.get_free_stakes::<T>() > T::WPhaMinBalance::get() {
let wpha_min = wrapped_balances::Pallet::<T>::min_balance();
while pool_info.get_free_stakes::<T>() > wpha_min {
if let Some(withdraw) = pool_info.withdraw_queue.front().cloned() {
// Must clear the pending reward before any stake change
let mut withdraw_nft_guard =
Expand Down
20 changes: 16 additions & 4 deletions pallets/phala/src/compute/computation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,16 @@ pub mod pallet {
type UpdateTokenomicOrigin: EnsureOrigin<Self::RuntimeOrigin>;
type SetBudgetOrigins: EnsureOrigin<Self::RuntimeOrigin>;
type SetContractRootOrigins: EnsureOrigin<Self::RuntimeOrigin>;

/// Enable worker register time checking when trying to add it to a pool.
///
/// The chain requires that workers must be registered after the Gatekeeper is launched
/// in order to be added to a stakepool. This makes sure the Gatekeeper tracks all events
/// for all workers being computing. However, on Khala network, workers registered earlier
/// didn't record there register time, so we need to disable this checking for Khala.
///
/// DISABLE THIS FOR KHALA ONLY.
type CheckWorkerRegisterTime: Get<bool>;
}

const STORAGE_VERSION: StorageVersion = StorageVersion::new(7);
Expand Down Expand Up @@ -871,10 +881,12 @@ pub mod pallet {
pub fn bind(session: T::AccountId, pubkey: WorkerPublicKey) -> DispatchResult {
let worker =
registry::Workers::<T>::get(&pubkey).ok_or(Error::<T>::WorkerNotRegistered)?;
ensure!(
registry::Pallet::<T>::is_worker_registered_after_gk_launched(&pubkey),
Error::<T>::WorkerReregisterNeeded
);
if T::CheckWorkerRegisterTime::get() {
ensure!(
registry::Pallet::<T>::is_worker_registered_after_gk_launched(&pubkey),
Error::<T>::WorkerReregisterNeeded
);
}
// Check the worker has finished the benchmark
ensure!(worker.initial_score != None, Error::<T>::BenchmarkMissing);
// Check worker and worker not bound
Expand Down
100 changes: 64 additions & 36 deletions pallets/phala/src/compute/stake_pool_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,16 @@ pub mod pallet {
worker: WorkerPublicKey,
amount: BalanceOf<T>,
},

/// Some to-distribute reward is dismissed because the amount is too tiny (dust)
///
/// There's no affected state.
RewardToOwnerDismissedDust { pid: u64, amount: BalanceOf<T> },

/// Some to-distribute reward is dismissed because the amount is too tiny (dust)
///
/// There's no affected state.
RewardToDistributionDismissedDust { pid: u64, amount: BalanceOf<T> },
}

#[pallet::error]
Expand Down Expand Up @@ -1074,51 +1084,69 @@ pub mod pallet {
pool_info: &mut StakePool<T::AccountId, BalanceOf<T>>,
rewards: BalanceOf<T>,
) {
if rewards > Zero::zero() {
computation::Pallet::<T>::withdraw_subsidy_pool(
&<T as wrapped_balances::Config>::WrappedBalancesAccountId::get(),
rewards,
)
.expect("this should not happen");
if base_pool::balance_close_to_zero(pool_info.basepool.total_shares) {
Self::deposit_event(Event::<T>::RewardDismissedNoShare {
pid: pool_info.basepool.pid,
amount: rewards,
});
return;
}
let commission = pool_info.payout_commission.unwrap_or_default() * rewards;

wrapped_balances::Pallet::<T>::mint_into(
&pool_info.owner_reward_account,
commission,
)
.expect("mint into should be success");
let to_distribute = rewards - commission;
wrapped_balances::Pallet::<T>::mint_into(
&pool_info.basepool.pool_account_id,
to_distribute,
)
.expect("mint into should be success");
let distributed = if base_pool::is_nondust_balance(to_distribute) {
if rewards == Zero::zero() {
return;
}
// Dismiss if the reward is dust
if base_pool::balance_close_to_zero(rewards) {
Self::deposit_event(Event::<T>::RewardDismissedDust {
pid: pool_info.basepool.pid,
amount: rewards,
});
return;
}
// Dismiss if the share is dust (pool is frozen)
if base_pool::balance_close_to_zero(pool_info.basepool.total_shares) {
Self::deposit_event(Event::<T>::RewardDismissedNoShare {
pid: pool_info.basepool.pid,
amount: rewards,
});
return;
}
computation::Pallet::<T>::withdraw_subsidy_pool(
&<T as wrapped_balances::Config>::WrappedBalancesAccountId::get(),
rewards,
)
.expect("withdrawal from the subsidy pool should always success; qed.");
// Handle the owner commission. Be careful about minting as it may fail (dust)
let commission = pool_info.payout_commission.unwrap_or_default() * rewards;
let owner_minted = wrapped_balances::Pallet::<T>::mint_into(
&pool_info.owner_reward_account,
commission,
)
.expect("mint owner reward should succeed; qed.");
if !owner_minted {
Self::deposit_event(Event::<T>::RewardToOwnerDismissedDust {
pid: pool_info.basepool.pid,
amount: commission,
});
}
// Handle the to-distribute commission. Be careful about minting as it may fail (dust).
let to_distribute = rewards - commission;
let to_distribute_minted = wrapped_balances::Pallet::<T>::mint_into(
&pool_info.basepool.pool_account_id,
to_distribute,
)
.expect("mint to_distribute should succeed; qed.");
let distributed =
if to_distribute_minted && base_pool::is_nondust_balance(to_distribute) {
pool_info.basepool.distribute_reward::<T>(to_distribute);
true
} else if to_distribute > Zero::zero() {
Self::deposit_event(Event::<T>::RewardDismissedDust {
Self::deposit_event(Event::<T>::RewardToDistributionDismissedDust {
pid: pool_info.basepool.pid,
amount: to_distribute,
});
false
} else {
false
};
if distributed || commission > Zero::zero() {
Self::deposit_event(Event::<T>::RewardReceived {
pid: pool_info.basepool.pid,
to_owner: commission,
to_stakers: to_distribute,
});
}
if distributed || owner_minted {
Self::deposit_event(Event::<T>::RewardReceived {
pid: pool_info.basepool.pid,
to_owner: commission,
to_stakers: to_distribute,
});
}
}

Expand Down Expand Up @@ -1195,7 +1223,7 @@ pub mod pallet {
worker: info.pubkey,
amount: reward,
});
return;
continue;
}
};
let mut pool_info =
Expand Down
50 changes: 40 additions & 10 deletions pallets/phala/src/compute/wrapped_balances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod pallet {
use crate::registry;
use crate::vault;
use crate::{BalanceOf, NegativeImbalanceOf, PhalaConfig};
use frame_support::traits::tokens::{Fortitude, Precision};
use frame_support::{
pallet_prelude::*,
traits::{
Expand All @@ -19,7 +20,6 @@ pub mod pallet {
OnUnbalanced, StorageVersion,
},
};
use frame_support::traits::tokens::{Fortitude, Precision};
use frame_system::{pallet_prelude::*, RawOrigin};
use pallet_democracy::{AccountVote, ReferendumIndex, ReferendumInfo};
pub use rmrk_traits::primitives::{CollectionId, NftId};
Expand Down Expand Up @@ -85,10 +85,14 @@ pub mod pallet {

/// Mapping for users to their asset status proxys
#[pallet::storage]
#[pallet::getter(fn staker_account)]
pub type StakerAccounts<T: Config> =
StorageMap<_, Twox64Concat, T::AccountId, FinanceAccount<BalanceOf<T>>>;

/// Collect the unmintable dust
// TODO: since this is the imbalance, consider to mint it in the future.
#[pallet::storage]
pub type UnmintableDust<T: Config> = StorageValue<_, BalanceOf<T>, ValueQuery>;

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
Expand Down Expand Up @@ -379,9 +383,14 @@ pub mod pallet {
pub fn remove_dust(who: &T::AccountId, dust: BalanceOf<T>) {
debug_assert!(dust != Zero::zero());
if dust != Zero::zero() {
let actual_removed =
pallet_assets::Pallet::<T>::burn_from(T::WPhaAssetId::get(), who, dust, Precision::BestEffort, Fortitude::Force)
.expect("slash should success with correct amount: qed.");
let actual_removed = pallet_assets::Pallet::<T>::burn_from(
T::WPhaAssetId::get(),
who,
dust,
Precision::BestEffort,
Fortitude::Force,
)
.expect("slash should success with correct amount: qed.");
let (imbalance, _remaining) = <T as PhalaConfig>::Currency::slash(
&<computation::pallet::Pallet<T>>::account_id(),
dust,
Expand All @@ -394,10 +403,19 @@ pub mod pallet {
}
}

/// Mints some W-PHA
pub fn mint_into(target: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {
pallet_assets::Pallet::<T>::mint_into(T::WPhaAssetId::get(), target, amount)?;
Ok(())
/// Mints some W-PHA. If the amount is below ED, it returns Ok(false) and adds the dust
/// to `UnmintableDust`.
pub fn mint_into(
target: &T::AccountId,
amount: BalanceOf<T>,
) -> Result<bool, DispatchError> {
let wpha = T::WPhaAssetId::get();
let result = pallet_assets::Pallet::<T>::mint_into(wpha, target, amount);
if result == Err(sp_runtime::TokenError::BelowMinimum.into()) {
UnmintableDust::<T>::mutate(|value| *value += amount);
return Ok(false);
}
result.and(Ok(true))
}

/// Burns some W-PHA
Expand All @@ -407,7 +425,7 @@ pub mod pallet {
target,
amount,
Precision::BestEffort,
Fortitude::Force
Fortitude::Force,
)?;
Ok(())
}
Expand Down Expand Up @@ -499,5 +517,17 @@ pub mod pallet {
let vote_info = pallet_democracy::Pallet::<T>::referendum_info(vote_id);
matches!(vote_info, Some(ReferendumInfo::Ongoing(_)))
}

/// Returns the minimum balance of WPHA
pub fn min_balance() -> BalanceOf<T> {
if !<pallet_assets::pallet::Pallet<T> as Inspect<T::AccountId>>::asset_exists(
T::WPhaAssetId::get(),
) {
panic!("WPHA does not exist");
}
<pallet_assets::pallet::Pallet<T> as Inspect<T::AccountId>>::minimum_balance(
T::WPhaAssetId::get(),
)
}
}
}
9 changes: 4 additions & 5 deletions pallets/phala/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ parameter_types! {
pub const NoneAttestationEnabled: bool = true;
pub const VerifyPRuntime: bool = false;
pub const VerifyRelaychainGenesisBlockHash: bool = true;
pub const CheckWorkerRegisterTime: bool = true;
}
impl system::Config for Test {
type BaseCallFilter = frame_support::traits::Everything;
Expand Down Expand Up @@ -129,8 +130,8 @@ impl pallet_balances::Config for Test {
type ReserveIdentifier = [u8; 8];
type HoldIdentifier = ();
type FreezeIdentifier = ();
type MaxHolds = ();
type MaxFreezes = ();
type MaxHolds = ConstU32<1>;
type MaxFreezes = ConstU32<1>;
}

impl pallet_timestamp::Config for Test {
Expand Down Expand Up @@ -257,6 +258,7 @@ impl computation::Config for Test {
type UpdateTokenomicOrigin = EnsureRoot<Self::AccountId>;
type SetBudgetOrigins = EnsureSignedBy<SetBudgetMembers, Self::AccountId>;
type SetContractRootOrigins = EnsureRoot<Self::AccountId>;
type CheckWorkerRegisterTime = CheckWorkerRegisterTime;
}

parameter_types! {
Expand Down Expand Up @@ -402,7 +404,6 @@ impl vault::Config for Test {
impl base_pool::Config for Test {
type RuntimeEvent = RuntimeEvent;
type MigrationAccountId = ConstU64<1234>;
type WPhaMinBalance = WPhaMinBalance;
}

impl stake_pool::Config for Test {
Expand Down Expand Up @@ -473,14 +474,12 @@ pub fn take_events() -> Vec<RuntimeEvent> {
.into_iter()
.map(|evt| evt.event)
.collect::<Vec<_>>();
println!("event(): {evt:?}");
System::reset_events();
evt
}

pub fn take_messages() -> Vec<Message> {
let messages = PhalaMq::messages();
println!("messages(): {messages:?}");
mq::OutboundMessages::<Test>::kill();
messages
}
Expand Down
4 changes: 2 additions & 2 deletions pallets/phala/src/phat_tokenomic/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ impl pallet_balances::Config for Test {
type ReserveIdentifier = [u8; 8];
type HoldIdentifier = ();
type FreezeIdentifier = ();
type MaxHolds = ();
type MaxFreezes = ();
type MaxHolds = ConstU32<1>;
type MaxFreezes = ConstU32<1>;
}

impl pallet_timestamp::Config for Test {
Expand Down
Loading

0 comments on commit c4ba598

Please sign in to comment.