Skip to content
This repository was archived by the owner on Dec 1, 2025. It is now read-only.

Commit c4ba598

Browse files
committed
Sync Phala pallets to f87192b64d90b06d1d8415fb47a1adffea43cc45‘
1 parent 8e84358 commit c4ba598

8 files changed

Lines changed: 196 additions & 62 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pallets/phala/src/compute/base_pool.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ pub mod pallet {
7272
{
7373
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
7474
type MigrationAccountId: Get<Self::AccountId>;
75-
type WPhaMinBalance: Get<BalanceOf<Self>>;
7675
}
7776

7877
#[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq, RuntimeDebug)]
@@ -1032,7 +1031,8 @@ pub mod pallet {
10321031
None => return false,
10331032
};
10341033
let current_balance = bmul(nft.shares, &price);
1035-
if current_balance > T::WPhaMinBalance::get() {
1034+
let wpha_min = wrapped_balances::Pallet::<T>::min_balance();
1035+
if current_balance > wpha_min {
10361036
return false;
10371037
}
10381038
pool_info.total_shares -= nft.shares;
@@ -1068,7 +1068,8 @@ pub mod pallet {
10681068
None => return,
10691069
};
10701070

1071-
while pool_info.get_free_stakes::<T>() > T::WPhaMinBalance::get() {
1071+
let wpha_min = wrapped_balances::Pallet::<T>::min_balance();
1072+
while pool_info.get_free_stakes::<T>() > wpha_min {
10721073
if let Some(withdraw) = pool_info.withdraw_queue.front().cloned() {
10731074
// Must clear the pending reward before any stake change
10741075
let mut withdraw_nft_guard =

pallets/phala/src/compute/computation.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,16 @@ pub mod pallet {
210210
type UpdateTokenomicOrigin: EnsureOrigin<Self::RuntimeOrigin>;
211211
type SetBudgetOrigins: EnsureOrigin<Self::RuntimeOrigin>;
212212
type SetContractRootOrigins: EnsureOrigin<Self::RuntimeOrigin>;
213+
214+
/// Enable worker register time checking when trying to add it to a pool.
215+
///
216+
/// The chain requires that workers must be registered after the Gatekeeper is launched
217+
/// in order to be added to a stakepool. This makes sure the Gatekeeper tracks all events
218+
/// for all workers being computing. However, on Khala network, workers registered earlier
219+
/// didn't record there register time, so we need to disable this checking for Khala.
220+
///
221+
/// DISABLE THIS FOR KHALA ONLY.
222+
type CheckWorkerRegisterTime: Get<bool>;
213223
}
214224

215225
const STORAGE_VERSION: StorageVersion = StorageVersion::new(7);
@@ -871,10 +881,12 @@ pub mod pallet {
871881
pub fn bind(session: T::AccountId, pubkey: WorkerPublicKey) -> DispatchResult {
872882
let worker =
873883
registry::Workers::<T>::get(&pubkey).ok_or(Error::<T>::WorkerNotRegistered)?;
874-
ensure!(
875-
registry::Pallet::<T>::is_worker_registered_after_gk_launched(&pubkey),
876-
Error::<T>::WorkerReregisterNeeded
877-
);
884+
if T::CheckWorkerRegisterTime::get() {
885+
ensure!(
886+
registry::Pallet::<T>::is_worker_registered_after_gk_launched(&pubkey),
887+
Error::<T>::WorkerReregisterNeeded
888+
);
889+
}
878890
// Check the worker has finished the benchmark
879891
ensure!(worker.initial_score != None, Error::<T>::BenchmarkMissing);
880892
// Check worker and worker not bound

pallets/phala/src/compute/stake_pool_v2.rs

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,16 @@ pub mod pallet {
227227
worker: WorkerPublicKey,
228228
amount: BalanceOf<T>,
229229
},
230+
231+
/// Some to-distribute reward is dismissed because the amount is too tiny (dust)
232+
///
233+
/// There's no affected state.
234+
RewardToOwnerDismissedDust { pid: u64, amount: BalanceOf<T> },
235+
236+
/// Some to-distribute reward is dismissed because the amount is too tiny (dust)
237+
///
238+
/// There's no affected state.
239+
RewardToDistributionDismissedDust { pid: u64, amount: BalanceOf<T> },
230240
}
231241

232242
#[pallet::error]
@@ -1074,51 +1084,69 @@ pub mod pallet {
10741084
pool_info: &mut StakePool<T::AccountId, BalanceOf<T>>,
10751085
rewards: BalanceOf<T>,
10761086
) {
1077-
if rewards > Zero::zero() {
1078-
computation::Pallet::<T>::withdraw_subsidy_pool(
1079-
&<T as wrapped_balances::Config>::WrappedBalancesAccountId::get(),
1080-
rewards,
1081-
)
1082-
.expect("this should not happen");
1083-
if base_pool::balance_close_to_zero(pool_info.basepool.total_shares) {
1084-
Self::deposit_event(Event::<T>::RewardDismissedNoShare {
1085-
pid: pool_info.basepool.pid,
1086-
amount: rewards,
1087-
});
1088-
return;
1089-
}
1090-
let commission = pool_info.payout_commission.unwrap_or_default() * rewards;
1091-
1092-
wrapped_balances::Pallet::<T>::mint_into(
1093-
&pool_info.owner_reward_account,
1094-
commission,
1095-
)
1096-
.expect("mint into should be success");
1097-
let to_distribute = rewards - commission;
1098-
wrapped_balances::Pallet::<T>::mint_into(
1099-
&pool_info.basepool.pool_account_id,
1100-
to_distribute,
1101-
)
1102-
.expect("mint into should be success");
1103-
let distributed = if base_pool::is_nondust_balance(to_distribute) {
1087+
if rewards == Zero::zero() {
1088+
return;
1089+
}
1090+
// Dismiss if the reward is dust
1091+
if base_pool::balance_close_to_zero(rewards) {
1092+
Self::deposit_event(Event::<T>::RewardDismissedDust {
1093+
pid: pool_info.basepool.pid,
1094+
amount: rewards,
1095+
});
1096+
return;
1097+
}
1098+
// Dismiss if the share is dust (pool is frozen)
1099+
if base_pool::balance_close_to_zero(pool_info.basepool.total_shares) {
1100+
Self::deposit_event(Event::<T>::RewardDismissedNoShare {
1101+
pid: pool_info.basepool.pid,
1102+
amount: rewards,
1103+
});
1104+
return;
1105+
}
1106+
computation::Pallet::<T>::withdraw_subsidy_pool(
1107+
&<T as wrapped_balances::Config>::WrappedBalancesAccountId::get(),
1108+
rewards,
1109+
)
1110+
.expect("withdrawal from the subsidy pool should always success; qed.");
1111+
// Handle the owner commission. Be careful about minting as it may fail (dust)
1112+
let commission = pool_info.payout_commission.unwrap_or_default() * rewards;
1113+
let owner_minted = wrapped_balances::Pallet::<T>::mint_into(
1114+
&pool_info.owner_reward_account,
1115+
commission,
1116+
)
1117+
.expect("mint owner reward should succeed; qed.");
1118+
if !owner_minted {
1119+
Self::deposit_event(Event::<T>::RewardToOwnerDismissedDust {
1120+
pid: pool_info.basepool.pid,
1121+
amount: commission,
1122+
});
1123+
}
1124+
// Handle the to-distribute commission. Be careful about minting as it may fail (dust).
1125+
let to_distribute = rewards - commission;
1126+
let to_distribute_minted = wrapped_balances::Pallet::<T>::mint_into(
1127+
&pool_info.basepool.pool_account_id,
1128+
to_distribute,
1129+
)
1130+
.expect("mint to_distribute should succeed; qed.");
1131+
let distributed =
1132+
if to_distribute_minted && base_pool::is_nondust_balance(to_distribute) {
11041133
pool_info.basepool.distribute_reward::<T>(to_distribute);
11051134
true
11061135
} else if to_distribute > Zero::zero() {
1107-
Self::deposit_event(Event::<T>::RewardDismissedDust {
1136+
Self::deposit_event(Event::<T>::RewardToDistributionDismissedDust {
11081137
pid: pool_info.basepool.pid,
11091138
amount: to_distribute,
11101139
});
11111140
false
11121141
} else {
11131142
false
11141143
};
1115-
if distributed || commission > Zero::zero() {
1116-
Self::deposit_event(Event::<T>::RewardReceived {
1117-
pid: pool_info.basepool.pid,
1118-
to_owner: commission,
1119-
to_stakers: to_distribute,
1120-
});
1121-
}
1144+
if distributed || owner_minted {
1145+
Self::deposit_event(Event::<T>::RewardReceived {
1146+
pid: pool_info.basepool.pid,
1147+
to_owner: commission,
1148+
to_stakers: to_distribute,
1149+
});
11221150
}
11231151
}
11241152

@@ -1195,7 +1223,7 @@ pub mod pallet {
11951223
worker: info.pubkey,
11961224
amount: reward,
11971225
});
1198-
return;
1226+
continue;
11991227
}
12001228
};
12011229
let mut pool_info =

pallets/phala/src/compute/wrapped_balances.rs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub mod pallet {
99
use crate::registry;
1010
use crate::vault;
1111
use crate::{BalanceOf, NegativeImbalanceOf, PhalaConfig};
12+
use frame_support::traits::tokens::{Fortitude, Precision};
1213
use frame_support::{
1314
pallet_prelude::*,
1415
traits::{
@@ -19,7 +20,6 @@ pub mod pallet {
1920
OnUnbalanced, StorageVersion,
2021
},
2122
};
22-
use frame_support::traits::tokens::{Fortitude, Precision};
2323
use frame_system::{pallet_prelude::*, RawOrigin};
2424
use pallet_democracy::{AccountVote, ReferendumIndex, ReferendumInfo};
2525
pub use rmrk_traits::primitives::{CollectionId, NftId};
@@ -85,10 +85,14 @@ pub mod pallet {
8585

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

91+
/// Collect the unmintable dust
92+
// TODO: since this is the imbalance, consider to mint it in the future.
93+
#[pallet::storage]
94+
pub type UnmintableDust<T: Config> = StorageValue<_, BalanceOf<T>, ValueQuery>;
95+
9296
#[pallet::event]
9397
#[pallet::generate_deposit(pub(super) fn deposit_event)]
9498
pub enum Event<T: Config> {
@@ -379,9 +383,14 @@ pub mod pallet {
379383
pub fn remove_dust(who: &T::AccountId, dust: BalanceOf<T>) {
380384
debug_assert!(dust != Zero::zero());
381385
if dust != Zero::zero() {
382-
let actual_removed =
383-
pallet_assets::Pallet::<T>::burn_from(T::WPhaAssetId::get(), who, dust, Precision::BestEffort, Fortitude::Force)
384-
.expect("slash should success with correct amount: qed.");
386+
let actual_removed = pallet_assets::Pallet::<T>::burn_from(
387+
T::WPhaAssetId::get(),
388+
who,
389+
dust,
390+
Precision::BestEffort,
391+
Fortitude::Force,
392+
)
393+
.expect("slash should success with correct amount: qed.");
385394
let (imbalance, _remaining) = <T as PhalaConfig>::Currency::slash(
386395
&<computation::pallet::Pallet<T>>::account_id(),
387396
dust,
@@ -394,10 +403,19 @@ pub mod pallet {
394403
}
395404
}
396405

397-
/// Mints some W-PHA
398-
pub fn mint_into(target: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {
399-
pallet_assets::Pallet::<T>::mint_into(T::WPhaAssetId::get(), target, amount)?;
400-
Ok(())
406+
/// Mints some W-PHA. If the amount is below ED, it returns Ok(false) and adds the dust
407+
/// to `UnmintableDust`.
408+
pub fn mint_into(
409+
target: &T::AccountId,
410+
amount: BalanceOf<T>,
411+
) -> Result<bool, DispatchError> {
412+
let wpha = T::WPhaAssetId::get();
413+
let result = pallet_assets::Pallet::<T>::mint_into(wpha, target, amount);
414+
if result == Err(sp_runtime::TokenError::BelowMinimum.into()) {
415+
UnmintableDust::<T>::mutate(|value| *value += amount);
416+
return Ok(false);
417+
}
418+
result.and(Ok(true))
401419
}
402420

403421
/// Burns some W-PHA
@@ -407,7 +425,7 @@ pub mod pallet {
407425
target,
408426
amount,
409427
Precision::BestEffort,
410-
Fortitude::Force
428+
Fortitude::Force,
411429
)?;
412430
Ok(())
413431
}
@@ -499,5 +517,17 @@ pub mod pallet {
499517
let vote_info = pallet_democracy::Pallet::<T>::referendum_info(vote_id);
500518
matches!(vote_info, Some(ReferendumInfo::Ongoing(_)))
501519
}
520+
521+
/// Returns the minimum balance of WPHA
522+
pub fn min_balance() -> BalanceOf<T> {
523+
if !<pallet_assets::pallet::Pallet<T> as Inspect<T::AccountId>>::asset_exists(
524+
T::WPhaAssetId::get(),
525+
) {
526+
panic!("WPHA does not exist");
527+
}
528+
<pallet_assets::pallet::Pallet<T> as Inspect<T::AccountId>>::minimum_balance(
529+
T::WPhaAssetId::get(),
530+
)
531+
}
502532
}
503533
}

pallets/phala/src/mock.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ parameter_types! {
7676
pub const NoneAttestationEnabled: bool = true;
7777
pub const VerifyPRuntime: bool = false;
7878
pub const VerifyRelaychainGenesisBlockHash: bool = true;
79+
pub const CheckWorkerRegisterTime: bool = true;
7980
}
8081
impl system::Config for Test {
8182
type BaseCallFilter = frame_support::traits::Everything;
@@ -129,8 +130,8 @@ impl pallet_balances::Config for Test {
129130
type ReserveIdentifier = [u8; 8];
130131
type HoldIdentifier = ();
131132
type FreezeIdentifier = ();
132-
type MaxHolds = ();
133-
type MaxFreezes = ();
133+
type MaxHolds = ConstU32<1>;
134+
type MaxFreezes = ConstU32<1>;
134135
}
135136

136137
impl pallet_timestamp::Config for Test {
@@ -257,6 +258,7 @@ impl computation::Config for Test {
257258
type UpdateTokenomicOrigin = EnsureRoot<Self::AccountId>;
258259
type SetBudgetOrigins = EnsureSignedBy<SetBudgetMembers, Self::AccountId>;
259260
type SetContractRootOrigins = EnsureRoot<Self::AccountId>;
261+
type CheckWorkerRegisterTime = CheckWorkerRegisterTime;
260262
}
261263

262264
parameter_types! {
@@ -402,7 +404,6 @@ impl vault::Config for Test {
402404
impl base_pool::Config for Test {
403405
type RuntimeEvent = RuntimeEvent;
404406
type MigrationAccountId = ConstU64<1234>;
405-
type WPhaMinBalance = WPhaMinBalance;
406407
}
407408

408409
impl stake_pool::Config for Test {
@@ -473,14 +474,12 @@ pub fn take_events() -> Vec<RuntimeEvent> {
473474
.into_iter()
474475
.map(|evt| evt.event)
475476
.collect::<Vec<_>>();
476-
println!("event(): {evt:?}");
477477
System::reset_events();
478478
evt
479479
}
480480

481481
pub fn take_messages() -> Vec<Message> {
482482
let messages = PhalaMq::messages();
483-
println!("messages(): {messages:?}");
484483
mq::OutboundMessages::<Test>::kill();
485484
messages
486485
}

pallets/phala/src/phat_tokenomic/tests/mock.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ impl pallet_balances::Config for Test {
8080
type ReserveIdentifier = [u8; 8];
8181
type HoldIdentifier = ();
8282
type FreezeIdentifier = ();
83-
type MaxHolds = ();
84-
type MaxFreezes = ();
83+
type MaxHolds = ConstU32<1>;
84+
type MaxFreezes = ConstU32<1>;
8585
}
8686

8787
impl pallet_timestamp::Config for Test {

0 commit comments

Comments
 (0)