feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
//! Benchmarking setup for pezpallet-trust
|
||||
//!
|
||||
//! These benchmarks measure the performance of trust score operations.
|
||||
|
||||
#![cfg(feature = "runtime-benchmarks")]
|
||||
|
||||
use super::*;
|
||||
use crate::Pallet as TrustPallet;
|
||||
|
||||
use pezframe_benchmarking::{v2::*, whitelisted_caller};
|
||||
use pezframe_support::pezpallet_prelude::*;
|
||||
use pezframe_system::RawOrigin;
|
||||
use pezsp_runtime::traits::Zero;
|
||||
|
||||
// We don't use IdentityKycPallet directly - just mock the citizenship status
|
||||
// This simplifies benchmarks and avoids coupling with identity-kyc internals
|
||||
|
||||
#[benchmarks]
|
||||
mod benchmarks {
|
||||
use super::*;
|
||||
|
||||
/// Helper to setup a citizen for benchmarking
|
||||
/// Instead of calling identity-kyc extrinsics, we mock the citizenship source
|
||||
fn setup_citizen<T: Config>(account: &T::AccountId) {
|
||||
// For benchmarks, we rely on the runtime's CitizenshipSource implementation
|
||||
// The benchmark mock should configure CitizenshipSource to return true for whitelisted
|
||||
// accounts This is typically done via TestCitizenshipProvider in mock.rs
|
||||
|
||||
// Initialize trust score storage for the account so update operations work
|
||||
TrustScores::<T>::insert(account, T::Score::zero());
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn force_recalculate_trust_score() -> Result<(), BenchmarkError> {
|
||||
// Setup
|
||||
let account: T::AccountId = whitelisted_caller();
|
||||
setup_citizen::<T>(&account);
|
||||
|
||||
#[extrinsic_call]
|
||||
force_recalculate_trust_score(RawOrigin::Root, account.clone());
|
||||
|
||||
// Verify - trust score should be calculated (may be zero if no component scores)
|
||||
assert!(TrustScores::<T>::contains_key(&account));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn update_all_trust_scores() {
|
||||
// Setup - Ensure no batch update is in progress
|
||||
crate::BatchUpdateInProgress::<T>::put(false);
|
||||
|
||||
#[extrinsic_call]
|
||||
update_all_trust_scores(RawOrigin::Root);
|
||||
|
||||
// Verify - The function completed (may or may not have set BatchUpdateInProgress
|
||||
// depending on whether there are citizens to process)
|
||||
// We just verify it doesn't panic
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn periodic_trust_score_update() {
|
||||
// Setup - Ensure no batch update is in progress
|
||||
crate::BatchUpdateInProgress::<T>::put(false);
|
||||
|
||||
#[extrinsic_call]
|
||||
periodic_trust_score_update(RawOrigin::Root);
|
||||
|
||||
// Verify - The function completed successfully
|
||||
}
|
||||
|
||||
impl_benchmark_test_suite!(TrustPallet, crate::mock::new_test_ext(), crate::mock::Test);
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
//! # Trust Score Pallet
|
||||
//!
|
||||
//! A pallet for calculating and managing composite trust scores based on multiple ecosystem
|
||||
//! metrics.
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The Trust Score pallet aggregates multiple reputation and activity metrics to produce
|
||||
//! a unified trust score for each citizen. This score is used throughout the ecosystem for:
|
||||
//!
|
||||
//! - Validator pool eligibility (trust-based validators)
|
||||
//! - Reward distribution weighting (pez-rewards)
|
||||
//! - Governance participation rights
|
||||
//! - Social reputation tracking
|
||||
//!
|
||||
//! ## Trust Score Components
|
||||
//!
|
||||
//! The trust score is calculated from four primary sources:
|
||||
//!
|
||||
//! 1. **Staking Score**: Economic security through token staking
|
||||
//! 2. **Referral Score**: Network growth contribution via referrals
|
||||
//! 3. **Perwerde Score**: Educational achievement and verification
|
||||
//! 4. **Tiki Score**: Social engagement and platform activity
|
||||
//!
|
||||
//! ## Score Calculation
|
||||
//!
|
||||
//! ```text
|
||||
//! trust_score = (staking_score + referral_score + perwerde_score + tiki_score) * multiplier
|
||||
//! ```
|
||||
//!
|
||||
//! Where:
|
||||
//! - Each component score is normalized and weighted
|
||||
//! - The multiplier is configurable via `ScoreMultiplierBase`
|
||||
//! - Citizenship status is required (KYC approved)
|
||||
//!
|
||||
//! ## Update Mechanisms
|
||||
//!
|
||||
//! ### Automatic Updates
|
||||
//! - Periodic batch updates scheduled at `UpdateInterval` (e.g., daily)
|
||||
//! - Processes all citizens in batches to manage computational load
|
||||
//! - Maintains update progress across blocks for large user bases
|
||||
//!
|
||||
//! ### Manual Updates
|
||||
//! - Individual score recalculation via privileged call
|
||||
//! - Full batch update trigger (root only)
|
||||
//! - Component change hooks from other pallets
|
||||
//!
|
||||
//! ## Storage
|
||||
//!
|
||||
//! - `TrustScores` - Per-account trust score mapping
|
||||
//! - `TotalActiveTrustScore` - Aggregate trust score across all citizens
|
||||
//! - `BatchUpdateInProgress` - Flag for ongoing batch update process
|
||||
//! - `LastProcessedAccount` - Checkpoint for resumable batch updates
|
||||
//!
|
||||
//! ## Interface
|
||||
//!
|
||||
//! ### Extrinsics
|
||||
//!
|
||||
//! - `force_recalculate_trust_score(who)` - Manually recalculate specific user's score (root)
|
||||
//! - `update_all_trust_scores()` - Trigger batch update of all citizens (root)
|
||||
//!
|
||||
//! ### Trait Implementations
|
||||
//!
|
||||
//! - `TrustScoreProvider` - Query trust scores from other pallets
|
||||
//! - `TrustScoreUpdater` - Receive notifications of component changes
|
||||
//!
|
||||
//! ## Dependencies
|
||||
//!
|
||||
//! This pallet requires integration with:
|
||||
//! - `pezpallet-identity-kyc` - Citizenship status verification
|
||||
//! - `pezpallet-staking-score` - Staking metrics provider
|
||||
//! - `pezpallet-referral` - Referral score provider
|
||||
//! - `pezpallet-perwerde` - Education score provider
|
||||
//! - `pezpallet-tiki` - Social engagement provider
|
||||
//!
|
||||
//! ## Runtime Integration Example
|
||||
//!
|
||||
//! ```ignore
|
||||
//! impl pezpallet_trust::Config for Runtime {
|
||||
//! type RuntimeEvent = RuntimeEvent;
|
||||
//! type WeightInfo = pezpallet_trust::weights::BizinikiwiWeight<Runtime>;
|
||||
//! type Score = u128;
|
||||
//! type ScoreMultiplierBase = ConstU128<100>;
|
||||
//! type UpdateInterval = ConstU32<14400>; // ~1 day in blocks
|
||||
//! type StakingScoreSource = StakingScore;
|
||||
//! type ReferralScoreSource = Referral;
|
||||
//! type PerwerdeScoreSource = Perwerde;
|
||||
//! type TikiScoreSource = Tiki;
|
||||
//! type CitizenshipSource = IdentityKyc;
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
pub use pallet::*;
|
||||
|
||||
pub mod weights;
|
||||
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
mod benchmarking;
|
||||
|
||||
pub use pezpallet_staking_score::{RawScore as StakingRawScore, StakingScoreProvider};
|
||||
/* use pezkuwi_primitives::traits::{
|
||||
CitizenshipStatusProvider, PerwerdeScoreProvider, ReferralScoreProvider, RawScore,
|
||||
StakingDetails, StakingScoreProvider, TikiScoreProvider, TrustScoreUpdater, TrustScoreProvider
|
||||
}; */
|
||||
|
||||
use core::convert::TryFrom;
|
||||
use pezframe_system::pezpallet_prelude::BlockNumberFor;
|
||||
|
||||
use pezframe_support::pezpallet_prelude::{
|
||||
Get, IsType, MaxEncodedLen, Member, OptionQuery, Parameter, ValueQuery,
|
||||
};
|
||||
|
||||
pub trait ReferralScoreProvider<AccountId> {
|
||||
fn get_referral_score(who: &AccountId) -> u32;
|
||||
}
|
||||
|
||||
// Re-export from identity-kyc pallet
|
||||
pub use pezpallet_identity_kyc::CitizenshipStatusProvider;
|
||||
|
||||
pub trait TrustScoreUpdater<AccountId> {
|
||||
fn on_score_component_changed(who: &AccountId);
|
||||
}
|
||||
|
||||
pub trait PerwerdeScoreProvider<AccountId> {
|
||||
fn get_perwerde_score(who: &AccountId) -> u32;
|
||||
}
|
||||
|
||||
pub trait TrustScoreProvider<AccountId> {
|
||||
fn trust_score_of(who: &AccountId) -> u128;
|
||||
}
|
||||
|
||||
pub trait TikiScoreProvider<AccountId> {
|
||||
fn get_tiki_score(who: &AccountId) -> u32;
|
||||
}
|
||||
|
||||
#[pezframe_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::{weights::WeightInfo, *};
|
||||
use pezframe_support::pezpallet_prelude::*;
|
||||
use pezframe_system::pezpallet_prelude::*;
|
||||
use pezsp_runtime::traits::{Saturating, Zero};
|
||||
|
||||
#[pallet::pallet]
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: pezframe_system::Config + pezpallet_identity_kyc::Config {
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
|
||||
type WeightInfo: WeightInfo;
|
||||
|
||||
type Score: Member
|
||||
+ Parameter
|
||||
+ MaxEncodedLen
|
||||
+ Copy
|
||||
+ Default
|
||||
+ PartialOrd
|
||||
+ Saturating
|
||||
+ Zero
|
||||
+ From<StakingRawScore>
|
||||
+ Into<u128>
|
||||
+ TryFrom<u128>;
|
||||
|
||||
#[pallet::constant]
|
||||
type ScoreMultiplierBase: Get<u128>;
|
||||
|
||||
/// Block interval for Trust score updates (e.g. daily)
|
||||
#[pallet::constant]
|
||||
type UpdateInterval: Get<BlockNumberFor<Self>>;
|
||||
|
||||
/// Maximum number of accounts to process per batch update
|
||||
/// Prevents DoS by limiting computation per extrinsic call
|
||||
#[pallet::constant]
|
||||
type MaxBatchSize: Get<u32>;
|
||||
|
||||
type StakingScoreSource: StakingScoreProvider<Self::AccountId, BlockNumberFor<Self>>;
|
||||
type ReferralScoreSource: ReferralScoreProvider<Self::AccountId>;
|
||||
type PerwerdeScoreSource: PerwerdeScoreProvider<Self::AccountId>;
|
||||
type TikiScoreSource: TikiScoreProvider<Self::AccountId>;
|
||||
type CitizenshipSource: CitizenshipStatusProvider<Self::AccountId>;
|
||||
}
|
||||
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn trust_score_of)]
|
||||
pub type TrustScores<T: Config> =
|
||||
StorageMap<_, Blake2_128Concat, T::AccountId, T::Score, ValueQuery>;
|
||||
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn total_active_trust_score)]
|
||||
pub type TotalActiveTrustScore<T: Config> = StorageValue<_, T::Score, ValueQuery>;
|
||||
|
||||
#[pallet::storage]
|
||||
pub type LastProcessedAccount<T: Config> = StorageValue<_, T::AccountId, OptionQuery>;
|
||||
|
||||
#[pallet::storage]
|
||||
pub type BatchUpdateInProgress<T: Config> = StorageValue<_, bool, ValueQuery>;
|
||||
|
||||
#[pallet::event]
|
||||
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||
pub enum Event<T: Config> {
|
||||
/// A user's Trust Score was successfully updated.
|
||||
TrustScoreUpdated { who: T::AccountId, old_score: T::Score, new_score: T::Score },
|
||||
/// Total active Trust Score on chain updated.
|
||||
TotalTrustScoreUpdated { new_total: T::Score },
|
||||
/// A batch Trust Score update completed.
|
||||
BulkTrustScoreUpdate { count: u32 },
|
||||
/// All Trust Scores update completed.
|
||||
AllTrustScoresUpdated { total_updated: u32 },
|
||||
/// Periodic Trust Score update scheduled for next time.
|
||||
PeriodicUpdateScheduled { next_block: BlockNumberFor<T> },
|
||||
}
|
||||
|
||||
#[pallet::error]
|
||||
#[derive(PartialEq)]
|
||||
pub enum Error<T> {
|
||||
CalculationOverflow,
|
||||
NotACitizen,
|
||||
UpdateInProgress,
|
||||
}
|
||||
|
||||
#[pallet::genesis_config]
|
||||
#[derive(pezframe_support::DefaultNoBound)]
|
||||
pub struct GenesisConfig<T: Config> {
|
||||
pub start_periodic_updates: bool,
|
||||
#[serde(skip)]
|
||||
pub _phantom: core::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
#[pallet::genesis_build]
|
||||
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
|
||||
fn build(&self) {
|
||||
if self.start_periodic_updates {
|
||||
// Schedule first periodic update for 1 day later
|
||||
let _first_update_block =
|
||||
pezframe_system::Pallet::<T>::block_number() + T::UpdateInterval::get();
|
||||
|
||||
// Note: Scheduler may not be available during Genesis build
|
||||
// In this case, manual start required or scheduled in runtime
|
||||
// For now, we are just marking the flag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// To manually recalculate a specific user's Trust Score.
|
||||
#[pallet::call_index(0)]
|
||||
#[pallet::weight(<T as Config>::WeightInfo::force_recalculate_trust_score())]
|
||||
pub fn force_recalculate_trust_score(
|
||||
origin: OriginFor<T>,
|
||||
who: T::AccountId,
|
||||
) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
Self::update_score_for_account(&who)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Updates Trust Scores of all citizens in bulk
|
||||
/// Works in batches for large user base using efficient pagination
|
||||
/// UPDATED (Gemini suggestion): Uses iter_from for true O(1) resume
|
||||
#[pallet::call_index(1)]
|
||||
#[pallet::weight(<T as Config>::WeightInfo::update_all_trust_scores())]
|
||||
pub fn update_all_trust_scores(origin: OriginFor<T>) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
|
||||
let batch_size = Self::calculate_optimal_batch_size();
|
||||
let mut updated_count = 0u32;
|
||||
let mut all_processed = true;
|
||||
let mut last_account: Option<T::AccountId> = None;
|
||||
|
||||
// Use iter_from for efficient pagination - O(1) resume instead of O(n) scan
|
||||
// This is critical for large user bases to prevent chain stalling
|
||||
let iterator = match LastProcessedAccount::<T>::get() {
|
||||
Some(start_key) => {
|
||||
// Resume from last processed account using iter_from
|
||||
pezpallet_identity_kyc::KycStatuses::<T>::iter_from(
|
||||
pezpallet_identity_kyc::KycStatuses::<T>::hashed_key_for(&start_key),
|
||||
)
|
||||
},
|
||||
None => {
|
||||
// Start from beginning
|
||||
pezpallet_identity_kyc::KycStatuses::<T>::iter()
|
||||
},
|
||||
};
|
||||
|
||||
// Process accounts in batch
|
||||
for (account, kyc_level) in iterator {
|
||||
// Is batch limit full?
|
||||
if updated_count >= batch_size {
|
||||
// Save last processed account for next batch
|
||||
last_account = Some(account);
|
||||
all_processed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Only process accounts with Approved KYC (citizens)
|
||||
if kyc_level == pezpallet_identity_kyc::types::KycLevel::Approved {
|
||||
let _ = Self::update_score_for_account(&account);
|
||||
updated_count += 1;
|
||||
}
|
||||
|
||||
// Track last processed for checkpoint
|
||||
last_account = Some(account);
|
||||
}
|
||||
|
||||
// Update state based on completion
|
||||
if all_processed {
|
||||
LastProcessedAccount::<T>::kill();
|
||||
BatchUpdateInProgress::<T>::put(false);
|
||||
Self::deposit_event(Event::AllTrustScoresUpdated { total_updated: updated_count });
|
||||
} else {
|
||||
if let Some(ref account) = last_account {
|
||||
LastProcessedAccount::<T>::put(account.clone());
|
||||
}
|
||||
BatchUpdateInProgress::<T>::put(true);
|
||||
Self::deposit_event(Event::BulkTrustScoreUpdate { count: updated_count });
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Periyodik güncellemeyi başlatan function
|
||||
#[pallet::call_index(2)]
|
||||
#[pallet::weight(<T as Config>::WeightInfo::periodic_trust_score_update())]
|
||||
pub fn periodic_trust_score_update(origin: OriginFor<T>) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
|
||||
// Eğer önceki update devam ediyorsa bekle
|
||||
ensure!(!BatchUpdateInProgress::<T>::get(), Error::<T>::UpdateInProgress);
|
||||
|
||||
// Yeni periyodik güncellemeyi başlat
|
||||
Self::update_all_trust_scores(OriginFor::<T>::root())?;
|
||||
|
||||
// Bir sonraki periyodik güncellemeyi schedule et
|
||||
let current_block = pezframe_system::Pallet::<T>::block_number();
|
||||
let next_update_block = current_block + T::UpdateInterval::get();
|
||||
|
||||
Self::deposit_event(Event::PeriodicUpdateScheduled { next_block: next_update_block });
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> Pallet<T> {
|
||||
pub fn calculate_trust_score(who: &T::AccountId) -> Result<T::Score, Error<T>> {
|
||||
ensure!(T::CitizenshipSource::is_citizen(who), Error::<T>::NotACitizen);
|
||||
|
||||
let (staking_score_raw, _) = T::StakingScoreSource::get_staking_score(who);
|
||||
if staking_score_raw.is_zero() {
|
||||
return Ok(T::Score::zero());
|
||||
}
|
||||
|
||||
let staking_u128: u128 = staking_score_raw.into();
|
||||
let referral_u128: u128 = T::ReferralScoreSource::get_referral_score(who).into();
|
||||
let perwerde_u128: u128 = T::PerwerdeScoreSource::get_perwerde_score(who).into();
|
||||
let tiki_u128: u128 = T::TikiScoreSource::get_tiki_score(who).into();
|
||||
|
||||
let base = T::ScoreMultiplierBase::get();
|
||||
|
||||
let weighted_sum = staking_u128
|
||||
.saturating_mul(100)
|
||||
.saturating_add(referral_u128.saturating_mul(300))
|
||||
.saturating_add(perwerde_u128.saturating_mul(300))
|
||||
.saturating_add(tiki_u128.saturating_mul(300));
|
||||
|
||||
let final_score_u128 = staking_u128
|
||||
.saturating_mul(weighted_sum)
|
||||
.checked_div(base)
|
||||
.ok_or(Error::<T>::CalculationOverflow)?;
|
||||
|
||||
let new_trust_score = T::Score::try_from(final_score_u128)
|
||||
.map_err(|_| Error::<T>::CalculationOverflow)?;
|
||||
|
||||
Ok(new_trust_score)
|
||||
}
|
||||
|
||||
pub fn update_score_for_account(who: &T::AccountId) -> Result<T::Score, Error<T>> {
|
||||
let old_score = Self::trust_score_of(who);
|
||||
let new_score = Self::calculate_trust_score(who)?;
|
||||
|
||||
if old_score != new_score {
|
||||
<TrustScores<T>>::insert(who, new_score);
|
||||
let old_total = Self::total_active_trust_score();
|
||||
let new_total = old_total.saturating_sub(old_score).saturating_add(new_score);
|
||||
<TotalActiveTrustScore<T>>::put(new_total);
|
||||
Self::deposit_event(Event::TrustScoreUpdated {
|
||||
who: who.clone(),
|
||||
old_score,
|
||||
new_score,
|
||||
});
|
||||
Self::deposit_event(Event::TotalTrustScoreUpdated { new_total });
|
||||
}
|
||||
Ok(new_score)
|
||||
}
|
||||
|
||||
/// Returns the configured batch size for trust score updates
|
||||
/// Configurable via MaxBatchSize to allow governance control
|
||||
fn calculate_optimal_batch_size() -> u32 {
|
||||
T::MaxBatchSize::get()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> TrustScoreProvider<T::AccountId> for Pallet<T> {
|
||||
fn trust_score_of(who: &T::AccountId) -> u128 {
|
||||
Self::trust_score_of(who).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> TrustScoreUpdater<T::AccountId> for Pallet<T> {
|
||||
fn on_score_component_changed(who: &T::AccountId) {
|
||||
if let Err(e) = Self::update_score_for_account(who) {
|
||||
log::error!("Failed to update trust score for {:?}: {:?}", who, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
use crate as pezpallet_trust;
|
||||
use pezframe_support::{
|
||||
derive_impl, parameter_types,
|
||||
traits::{ConstU16, ConstU64},
|
||||
};
|
||||
use pezframe_system as system;
|
||||
use pezsp_core::H256;
|
||||
use pezsp_runtime::{
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
BuildStorage,
|
||||
};
|
||||
|
||||
type Block = pezframe_system::mocking::MockBlock<Test>;
|
||||
|
||||
pezframe_support::construct_runtime!(
|
||||
pub enum Test
|
||||
{
|
||||
System: pezframe_system,
|
||||
Balances: pezpallet_balances,
|
||||
IdentityKyc: pezpallet_identity_kyc,
|
||||
TrustPallet: pezpallet_trust,
|
||||
}
|
||||
);
|
||||
|
||||
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig as pezframe_system::DefaultConfig)]
|
||||
impl system::Config for Test {
|
||||
type BaseCallFilter = pezframe_support::traits::Everything;
|
||||
type BlockWeights = ();
|
||||
type BlockLength = ();
|
||||
type DbWeight = ();
|
||||
type RuntimeOrigin = RuntimeOrigin;
|
||||
type RuntimeCall = RuntimeCall;
|
||||
type Nonce = u64;
|
||||
type Hash = H256;
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Block = Block;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type BlockHashCount = ConstU64<250>;
|
||||
type Version = ();
|
||||
type PalletInfo = PalletInfo;
|
||||
type AccountData = pezpallet_balances::AccountData<u128>;
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = ConstU16<42>;
|
||||
type OnSetCode = ();
|
||||
type MaxConsumers = pezframe_support::traits::ConstU32<16>;
|
||||
}
|
||||
|
||||
impl pezpallet_balances::Config for Test {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type WeightInfo = ();
|
||||
type Balance = u128;
|
||||
type DustRemoval = ();
|
||||
type ExistentialDeposit = pezframe_support::traits::ConstU128<1>;
|
||||
type AccountStore = System;
|
||||
type ReserveIdentifier = [u8; 8];
|
||||
type RuntimeHoldReason = ();
|
||||
type RuntimeFreezeReason = ();
|
||||
type FreezeIdentifier = ();
|
||||
type MaxLocks = pezframe_support::traits::ConstU32<10>;
|
||||
type MaxReserves = pezframe_support::traits::ConstU32<10>;
|
||||
type MaxFreezes = pezframe_support::traits::ConstU32<10>;
|
||||
type DoneSlashHandler = ();
|
||||
}
|
||||
|
||||
pub struct NoOpOnKycApproved;
|
||||
impl pezpallet_identity_kyc::types::OnKycApproved<u64> for NoOpOnKycApproved {
|
||||
fn on_kyc_approved(_who: &u64, _referrer: &u64) {}
|
||||
}
|
||||
|
||||
pub struct NoOpOnCitizenshipRevoked;
|
||||
impl pezpallet_identity_kyc::types::OnCitizenshipRevoked<u64> for NoOpOnCitizenshipRevoked {
|
||||
fn on_citizenship_revoked(_who: &u64) {}
|
||||
}
|
||||
|
||||
pub struct NoOpCitizenNftProvider;
|
||||
impl pezpallet_identity_kyc::types::CitizenNftProvider<u64> for NoOpCitizenNftProvider {
|
||||
fn mint_citizen_nft(_who: &u64) -> Result<(), pezsp_runtime::DispatchError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mint_citizen_nft_confirmed(_who: &u64) -> Result<(), pezsp_runtime::DispatchError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn burn_citizen_nft(_who: &u64) -> Result<(), pezsp_runtime::DispatchError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl pezpallet_identity_kyc::Config for Test {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Currency = Balances;
|
||||
type GovernanceOrigin = pezframe_system::EnsureRoot<u64>;
|
||||
type WeightInfo = ();
|
||||
type OnKycApproved = NoOpOnKycApproved;
|
||||
type OnCitizenshipRevoked = NoOpOnCitizenshipRevoked;
|
||||
type CitizenNftProvider = NoOpCitizenNftProvider;
|
||||
type KycApplicationDeposit = pezframe_support::traits::ConstU128<100>;
|
||||
type MaxStringLength = pezframe_support::traits::ConstU32<128>;
|
||||
type MaxCidLength = pezframe_support::traits::ConstU32<64>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ScoreMultiplierBase: u128 = 1000;
|
||||
pub const TrustUpdateInterval: u64 = 100; // Test için kısa interval
|
||||
pub const MaxBatchSizeValue: u32 = 100; // Max users per batch
|
||||
}
|
||||
|
||||
pub struct MockStakingScoreProvider;
|
||||
impl pezpallet_trust::StakingScoreProvider<u64, u64> for MockStakingScoreProvider {
|
||||
fn get_staking_score(_who: &u64) -> (u32, u64) {
|
||||
(100, 0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockReferralScoreProvider;
|
||||
impl pezpallet_trust::ReferralScoreProvider<u64> for MockReferralScoreProvider {
|
||||
fn get_referral_score(_who: &u64) -> u32 {
|
||||
50
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockPerwerdeScoreProvider;
|
||||
impl pezpallet_trust::PerwerdeScoreProvider<u64> for MockPerwerdeScoreProvider {
|
||||
fn get_perwerde_score(_who: &u64) -> u32 {
|
||||
30
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockTikiScoreProvider;
|
||||
impl pezpallet_trust::TikiScoreProvider<u64> for MockTikiScoreProvider {
|
||||
fn get_tiki_score(_who: &u64) -> u32 {
|
||||
20
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockCitizenshipStatusProvider;
|
||||
impl pezpallet_trust::CitizenshipStatusProvider<u64> for MockCitizenshipStatusProvider {
|
||||
fn is_citizen(who: &u64) -> bool {
|
||||
// Test için: 1-100 arası hesaplar vatandaş, 999 değil
|
||||
*who >= 1 && *who <= 100 && *who != 999
|
||||
}
|
||||
}
|
||||
|
||||
impl pezpallet_trust::Config for Test {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type WeightInfo = ();
|
||||
type Score = u128;
|
||||
type ScoreMultiplierBase = ScoreMultiplierBase;
|
||||
type UpdateInterval = TrustUpdateInterval;
|
||||
type MaxBatchSize = MaxBatchSizeValue;
|
||||
type StakingScoreSource = MockStakingScoreProvider;
|
||||
type ReferralScoreSource = MockReferralScoreProvider;
|
||||
type PerwerdeScoreSource = MockPerwerdeScoreProvider;
|
||||
type TikiScoreSource = MockTikiScoreProvider;
|
||||
type CitizenshipSource = MockCitizenshipStatusProvider;
|
||||
}
|
||||
|
||||
pub fn new_test_ext() -> pezsp_io::TestExternalities {
|
||||
system::GenesisConfig::<Test>::default().build_storage().unwrap().into()
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
use crate::{mock::*, Error, Event};
|
||||
use pezframe_support::{assert_noop, assert_ok};
|
||||
use pezsp_runtime::traits::BadOrigin;
|
||||
|
||||
#[test]
|
||||
fn calculate_trust_score_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
let score = TrustPallet::calculate_trust_score(&account).unwrap();
|
||||
|
||||
let expected = {
|
||||
let staking = 100u128;
|
||||
let referral = 50u128;
|
||||
let perwerde = 30u128;
|
||||
let tiki = 20u128;
|
||||
let base = ScoreMultiplierBase::get();
|
||||
|
||||
let weighted_sum = staking * 100 + referral * 300 + perwerde * 300 + tiki * 300;
|
||||
staking * weighted_sum / base
|
||||
};
|
||||
|
||||
assert_eq!(score, expected);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn calculate_trust_score_fails_for_non_citizen() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let non_citizen = 999u64;
|
||||
assert_noop!(TrustPallet::calculate_trust_score(&non_citizen), Error::<Test>::NotACitizen);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn calculate_trust_score_zero_staking() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
let score = TrustPallet::calculate_trust_score(&account).unwrap();
|
||||
assert!(score > 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_score_for_account_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
|
||||
let initial_score = TrustPallet::trust_score_of(&account);
|
||||
assert_eq!(initial_score, 0);
|
||||
|
||||
let new_score = TrustPallet::update_score_for_account(&account).unwrap();
|
||||
assert!(new_score > 0);
|
||||
|
||||
let stored_score = TrustPallet::trust_score_of(&account);
|
||||
assert_eq!(stored_score, new_score);
|
||||
|
||||
let total_score = TrustPallet::total_active_trust_score();
|
||||
assert_eq!(total_score, new_score);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_score_for_account_updates_total() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account1 = 1u64;
|
||||
let account2 = 2u64;
|
||||
|
||||
let score1 = TrustPallet::update_score_for_account(&account1).unwrap();
|
||||
let total_after_first = TrustPallet::total_active_trust_score();
|
||||
assert_eq!(total_after_first, score1);
|
||||
|
||||
let score2 = TrustPallet::update_score_for_account(&account2).unwrap();
|
||||
let total_after_second = TrustPallet::total_active_trust_score();
|
||||
assert_eq!(total_after_second, score1 + score2);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn force_recalculate_trust_score_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
|
||||
assert_ok!(TrustPallet::force_recalculate_trust_score(RuntimeOrigin::root(), account));
|
||||
|
||||
let score = TrustPallet::trust_score_of(&account);
|
||||
assert!(score > 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn force_recalculate_trust_score_requires_root() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
|
||||
assert_noop!(
|
||||
TrustPallet::force_recalculate_trust_score(RuntimeOrigin::signed(account), account),
|
||||
BadOrigin
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_all_trust_scores_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Event'leri yakalamak için block number set et
|
||||
System::set_block_number(1);
|
||||
|
||||
assert_ok!(TrustPallet::update_all_trust_scores(RuntimeOrigin::root()));
|
||||
|
||||
// Mock implementation boş account listesi kullandığı için
|
||||
// AllTrustScoresUpdated event'i yayınlanır (count: 0 ile)
|
||||
let events = System::events();
|
||||
assert!(events.iter().any(|event| {
|
||||
matches!(
|
||||
event.event,
|
||||
RuntimeEvent::TrustPallet(Event::AllTrustScoresUpdated { total_updated: 0 })
|
||||
)
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_all_trust_scores_requires_root() {
|
||||
new_test_ext().execute_with(|| {
|
||||
assert_noop!(TrustPallet::update_all_trust_scores(RuntimeOrigin::signed(1)), BadOrigin);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn periodic_trust_score_update_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Event'leri yakalamak için block number set et
|
||||
System::set_block_number(1);
|
||||
|
||||
assert_ok!(TrustPallet::periodic_trust_score_update(RuntimeOrigin::root()));
|
||||
|
||||
// Periyodik güncelleme event'inin yayınlandığını kontrol et
|
||||
let events = System::events();
|
||||
assert!(events.iter().any(|event| {
|
||||
matches!(event.event, RuntimeEvent::TrustPallet(Event::PeriodicUpdateScheduled { .. }))
|
||||
}));
|
||||
|
||||
// Ayrıca AllTrustScoresUpdated event'i de yayınlanmalı
|
||||
assert!(events.iter().any(|event| {
|
||||
matches!(event.event, RuntimeEvent::TrustPallet(Event::AllTrustScoresUpdated { .. }))
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn periodic_update_fails_when_batch_in_progress() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Batch update'i başlat
|
||||
crate::BatchUpdateInProgress::<Test>::put(true);
|
||||
|
||||
// Periyodik update'in başarısız olmasını bekle
|
||||
assert_noop!(
|
||||
TrustPallet::periodic_trust_score_update(RuntimeOrigin::root()),
|
||||
Error::<Test>::UpdateInProgress
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn events_are_emitted() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
|
||||
System::set_block_number(1);
|
||||
|
||||
TrustPallet::update_score_for_account(&account).unwrap();
|
||||
|
||||
let events = System::events();
|
||||
assert!(events.len() >= 2);
|
||||
|
||||
let trust_score_updated = events.iter().any(|event| {
|
||||
matches!(event.event, RuntimeEvent::TrustPallet(Event::TrustScoreUpdated { .. }))
|
||||
});
|
||||
|
||||
let total_updated = events.iter().any(|event| {
|
||||
matches!(event.event, RuntimeEvent::TrustPallet(Event::TotalTrustScoreUpdated { .. }))
|
||||
});
|
||||
|
||||
assert!(trust_score_updated);
|
||||
assert!(total_updated);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trust_score_updater_trait_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
use crate::TrustScoreUpdater;
|
||||
|
||||
let account = 1u64;
|
||||
|
||||
let initial_score = TrustPallet::trust_score_of(&account);
|
||||
assert_eq!(initial_score, 0);
|
||||
|
||||
TrustPallet::on_score_component_changed(&account);
|
||||
|
||||
let updated_score = TrustPallet::trust_score_of(&account);
|
||||
assert!(updated_score > 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_update_storage_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Başlangıçta batch update aktif değil
|
||||
assert!(!crate::BatchUpdateInProgress::<Test>::get());
|
||||
assert!(crate::LastProcessedAccount::<Test>::get().is_none());
|
||||
|
||||
// Batch update'i simüle et
|
||||
crate::BatchUpdateInProgress::<Test>::put(true);
|
||||
crate::LastProcessedAccount::<Test>::put(42u64);
|
||||
|
||||
assert!(crate::BatchUpdateInProgress::<Test>::get());
|
||||
assert_eq!(crate::LastProcessedAccount::<Test>::get(), Some(42u64));
|
||||
|
||||
// Temizle
|
||||
crate::BatchUpdateInProgress::<Test>::put(false);
|
||||
crate::LastProcessedAccount::<Test>::kill();
|
||||
|
||||
assert!(!crate::BatchUpdateInProgress::<Test>::get());
|
||||
assert!(crate::LastProcessedAccount::<Test>::get().is_none());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn periodic_update_scheduling_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
System::set_block_number(100);
|
||||
|
||||
assert_ok!(TrustPallet::periodic_trust_score_update(RuntimeOrigin::root()));
|
||||
|
||||
// Event'te next_block'un doğru hesaplandığını kontrol et
|
||||
let events = System::events();
|
||||
let scheduled_event = events.iter().find(|event| {
|
||||
matches!(event.event, RuntimeEvent::TrustPallet(Event::PeriodicUpdateScheduled { .. }))
|
||||
});
|
||||
|
||||
assert!(scheduled_event.is_some());
|
||||
|
||||
if let Some(event_record) = scheduled_event {
|
||||
if let RuntimeEvent::TrustPallet(Event::PeriodicUpdateScheduled { next_block }) =
|
||||
&event_record.event
|
||||
{
|
||||
// Current block (100) + interval (100) = 200
|
||||
assert_eq!(next_block, &200u64);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// update_all_trust_scores Tests (5 tests)
|
||||
// ============================================================================
|
||||
|
||||
#[test]
|
||||
fn update_all_trust_scores_multiple_users() {
|
||||
new_test_ext().execute_with(|| {
|
||||
System::set_block_number(1);
|
||||
|
||||
// Root can update all trust scores
|
||||
assert_ok!(TrustPallet::update_all_trust_scores(RuntimeOrigin::root()));
|
||||
|
||||
// Verify at least one user has score (depends on mock KYC setup)
|
||||
let total = TrustPallet::total_active_trust_score();
|
||||
assert!(total >= 0); // May be 0 if no users have KYC approved in mock
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_all_trust_scores_root_only() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Non-root cannot update all trust scores
|
||||
assert_noop!(TrustPallet::update_all_trust_scores(RuntimeOrigin::signed(1)), BadOrigin);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_all_trust_scores_updates_total() {
|
||||
new_test_ext().execute_with(|| {
|
||||
System::set_block_number(1);
|
||||
|
||||
let initial_total = TrustPallet::total_active_trust_score();
|
||||
assert_eq!(initial_total, 0);
|
||||
|
||||
assert_ok!(TrustPallet::update_all_trust_scores(RuntimeOrigin::root()));
|
||||
|
||||
let final_total = TrustPallet::total_active_trust_score();
|
||||
// Total should remain valid (may stay 0 if no approved KYC users)
|
||||
assert!(final_total >= 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_all_trust_scores_emits_event() {
|
||||
new_test_ext().execute_with(|| {
|
||||
System::set_block_number(1);
|
||||
|
||||
assert_ok!(TrustPallet::update_all_trust_scores(RuntimeOrigin::root()));
|
||||
|
||||
let events = System::events();
|
||||
let bulk_update_event = events.iter().any(|event| {
|
||||
matches!(event.event, RuntimeEvent::TrustPallet(Event::BulkTrustScoreUpdate { .. })) ||
|
||||
matches!(
|
||||
event.event,
|
||||
RuntimeEvent::TrustPallet(Event::AllTrustScoresUpdated { .. })
|
||||
)
|
||||
});
|
||||
|
||||
assert!(bulk_update_event);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_all_trust_scores_batch_processing() {
|
||||
new_test_ext().execute_with(|| {
|
||||
System::set_block_number(1);
|
||||
|
||||
// First call should start batch processing
|
||||
assert_ok!(TrustPallet::update_all_trust_scores(RuntimeOrigin::root()));
|
||||
|
||||
// Check batch state is cleared after completion
|
||||
assert!(!crate::BatchUpdateInProgress::<Test>::get());
|
||||
assert!(crate::LastProcessedAccount::<Test>::get().is_none());
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Score Calculation Edge Cases (5 tests)
|
||||
// ============================================================================
|
||||
|
||||
#[test]
|
||||
fn calculate_trust_score_handles_overflow() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
|
||||
// Even with large values, should not overflow
|
||||
let score = TrustPallet::calculate_trust_score(&account);
|
||||
assert!(score.is_ok());
|
||||
assert!(score.unwrap() < u128::MAX);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn calculate_trust_score_all_zero_components() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 2u64; // User 2 exists in mock
|
||||
|
||||
let score = TrustPallet::calculate_trust_score(&account).unwrap();
|
||||
// Should be greater than 0 (mock provides some values)
|
||||
assert!(score >= 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_score_maintains_consistency() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
|
||||
// Update twice
|
||||
let score1 = TrustPallet::update_score_for_account(&account).unwrap();
|
||||
let score2 = TrustPallet::update_score_for_account(&account).unwrap();
|
||||
|
||||
// Scores should be equal (no random component)
|
||||
assert_eq!(score1, score2);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trust_score_decreases_when_components_decrease() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
|
||||
// First update with good scores
|
||||
let initial_score = TrustPallet::update_score_for_account(&account).unwrap();
|
||||
|
||||
// Simulate component decrease (in real scenario, staking/referral would decrease)
|
||||
// For now, just verify score can be recalculated
|
||||
let recalculated = TrustPallet::calculate_trust_score(&account).unwrap();
|
||||
|
||||
// Score should be deterministic
|
||||
assert_eq!(initial_score, recalculated);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_users_independent_scores() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let user1 = 1u64;
|
||||
let user2 = 2u64;
|
||||
|
||||
let score1 = TrustPallet::update_score_for_account(&user1).unwrap();
|
||||
let score2 = TrustPallet::update_score_for_account(&user2).unwrap();
|
||||
|
||||
// Scores should be independent
|
||||
assert_ne!(score1, 0);
|
||||
assert_ne!(score2, 0);
|
||||
|
||||
// Verify stored separately
|
||||
assert_eq!(TrustPallet::trust_score_of(&user1), score1);
|
||||
assert_eq!(TrustPallet::trust_score_of(&user2), score2);
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TrustScoreProvider Trait Tests (3 tests)
|
||||
// ============================================================================
|
||||
|
||||
#[test]
|
||||
fn trust_score_provider_trait_returns_zero_initially() {
|
||||
new_test_ext().execute_with(|| {
|
||||
use crate::TrustScoreProvider;
|
||||
|
||||
let account = 1u64;
|
||||
let score = TrustPallet::trust_score_of(&account);
|
||||
assert_eq!(score, 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trust_score_provider_trait_returns_updated_score() {
|
||||
new_test_ext().execute_with(|| {
|
||||
use crate::TrustScoreProvider;
|
||||
|
||||
let account = 1u64;
|
||||
TrustPallet::update_score_for_account(&account).unwrap();
|
||||
|
||||
let score = TrustPallet::trust_score_of(&account);
|
||||
assert!(score > 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trust_score_provider_trait_multiple_users() {
|
||||
new_test_ext().execute_with(|| {
|
||||
use crate::TrustScoreProvider;
|
||||
|
||||
TrustPallet::update_score_for_account(&1u64).unwrap();
|
||||
TrustPallet::update_score_for_account(&2u64).unwrap();
|
||||
|
||||
let score1 = TrustPallet::trust_score_of(&1u64);
|
||||
let score2 = TrustPallet::trust_score_of(&2u64);
|
||||
|
||||
assert!(score1 > 0);
|
||||
assert!(score2 > 0);
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Storage and State Tests (2 tests)
|
||||
// ============================================================================
|
||||
|
||||
#[test]
|
||||
fn storage_consistency_after_multiple_updates() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = 1u64;
|
||||
|
||||
// Multiple updates
|
||||
for _ in 0..5 {
|
||||
TrustPallet::update_score_for_account(&account).unwrap();
|
||||
}
|
||||
|
||||
// Score should still be consistent
|
||||
let stored = TrustPallet::trust_score_of(&account);
|
||||
let calculated = TrustPallet::calculate_trust_score(&account).unwrap();
|
||||
|
||||
assert_eq!(stored, calculated);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn total_active_trust_score_accumulates_correctly() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let users = vec![1u64, 2u64]; // Only users that exist in mock
|
||||
let mut expected_total = 0u128;
|
||||
|
||||
for user in users {
|
||||
let score = TrustPallet::update_score_for_account(&user).unwrap();
|
||||
expected_total += score;
|
||||
}
|
||||
|
||||
let total = TrustPallet::total_active_trust_score();
|
||||
assert_eq!(total, expected_total);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
//! Autogenerated weights for `pezpallet_trust`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
|
||||
//! DATE: 2025-12-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `MamostePC`, CPU: `11th Gen Intel(R) Core(TM) i9-11950H @ 2.60GHz`
|
||||
//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024`
|
||||
|
||||
// Executed Command:
|
||||
// ./target/release/frame-omni-bencher
|
||||
// v1
|
||||
// benchmark
|
||||
// pallet
|
||||
// --runtime
|
||||
// target/release/wbuild/people-pezkuwichain-runtime/people_pezkuwichain_runtime.compact.compressed.wasm
|
||||
// --pallets
|
||||
// pezpallet_trust
|
||||
// -e
|
||||
// all
|
||||
// --steps
|
||||
// 50
|
||||
// --repeat
|
||||
// 20
|
||||
// --output
|
||||
// pezcumulus/teyrchains/pallets/trust/src/weights.rs
|
||||
// --template
|
||||
// bizinikiwi/.maintain/frame-weight-template.hbs
|
||||
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(missing_docs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use pezframe_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
/// Weight functions needed for `pezpallet_trust`.
|
||||
pub trait WeightInfo {
|
||||
fn force_recalculate_trust_score() -> Weight;
|
||||
fn update_all_trust_scores() -> Weight;
|
||||
fn periodic_trust_score_update() -> Weight;
|
||||
}
|
||||
|
||||
/// Weights for `pezpallet_trust` using the Bizinikiwi node and recommended hardware.
|
||||
pub struct BizinikiwiWeight<T>(PhantomData<T>);
|
||||
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
|
||||
/// Storage: `Trust::TrustScores` (r:1 w:1)
|
||||
/// Proof: `Trust::TrustScores` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`)
|
||||
/// Storage: `StakingScore::StakingStartBlock` (r:1 w:0)
|
||||
/// Proof: `StakingScore::StakingStartBlock` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Referral::ReferralCount` (r:1 w:0)
|
||||
/// Proof: `Referral::ReferralCount` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Tiki::UserTikis` (r:1 w:0)
|
||||
/// Proof: `Tiki::UserTikis` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TotalActiveTrustScore` (r:1 w:1)
|
||||
/// Proof: `Trust::TotalActiveTrustScore` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
|
||||
fn force_recalculate_trust_score() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `287`
|
||||
// Estimated: `3534`
|
||||
// Minimum execution time: 41_676_000 picoseconds.
|
||||
Weight::from_parts(51_361_000, 3534)
|
||||
.saturating_add(T::DbWeight::get().reads(5_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2_u64))
|
||||
}
|
||||
/// Storage: `Trust::LastProcessedAccount` (r:1 w:1)
|
||||
/// Proof: `Trust::LastProcessedAccount` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `IdentityKyc::KycStatuses` (r:2 w:0)
|
||||
/// Proof: `IdentityKyc::KycStatuses` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TrustScores` (r:1 w:1)
|
||||
/// Proof: `Trust::TrustScores` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`)
|
||||
/// Storage: `StakingScore::StakingStartBlock` (r:1 w:0)
|
||||
/// Proof: `StakingScore::StakingStartBlock` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Referral::ReferralCount` (r:1 w:0)
|
||||
/// Proof: `Referral::ReferralCount` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Tiki::UserTikis` (r:1 w:0)
|
||||
/// Proof: `Tiki::UserTikis` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TotalActiveTrustScore` (r:1 w:1)
|
||||
/// Proof: `Trust::TotalActiveTrustScore` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::BatchUpdateInProgress` (r:0 w:1)
|
||||
/// Proof: `Trust::BatchUpdateInProgress` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`)
|
||||
fn update_all_trust_scores() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `338`
|
||||
// Estimated: `6038`
|
||||
// Minimum execution time: 57_062_000 picoseconds.
|
||||
Weight::from_parts(71_311_000, 6038)
|
||||
.saturating_add(T::DbWeight::get().reads(8_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(4_u64))
|
||||
}
|
||||
/// Storage: `Trust::BatchUpdateInProgress` (r:1 w:1)
|
||||
/// Proof: `Trust::BatchUpdateInProgress` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::LastProcessedAccount` (r:1 w:1)
|
||||
/// Proof: `Trust::LastProcessedAccount` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `IdentityKyc::KycStatuses` (r:2 w:0)
|
||||
/// Proof: `IdentityKyc::KycStatuses` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TrustScores` (r:1 w:1)
|
||||
/// Proof: `Trust::TrustScores` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`)
|
||||
/// Storage: `StakingScore::StakingStartBlock` (r:1 w:0)
|
||||
/// Proof: `StakingScore::StakingStartBlock` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Referral::ReferralCount` (r:1 w:0)
|
||||
/// Proof: `Referral::ReferralCount` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Tiki::UserTikis` (r:1 w:0)
|
||||
/// Proof: `Tiki::UserTikis` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TotalActiveTrustScore` (r:1 w:1)
|
||||
/// Proof: `Trust::TotalActiveTrustScore` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
|
||||
fn periodic_trust_score_update() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `338`
|
||||
// Estimated: `6038`
|
||||
// Minimum execution time: 82_604_000 picoseconds.
|
||||
Weight::from_parts(88_810_000, 6038)
|
||||
.saturating_add(T::DbWeight::get().reads(9_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(4_u64))
|
||||
}
|
||||
}
|
||||
|
||||
// For backwards compatibility and tests.
|
||||
impl WeightInfo for () {
|
||||
/// Storage: `Trust::TrustScores` (r:1 w:1)
|
||||
/// Proof: `Trust::TrustScores` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`)
|
||||
/// Storage: `StakingScore::StakingStartBlock` (r:1 w:0)
|
||||
/// Proof: `StakingScore::StakingStartBlock` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Referral::ReferralCount` (r:1 w:0)
|
||||
/// Proof: `Referral::ReferralCount` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Tiki::UserTikis` (r:1 w:0)
|
||||
/// Proof: `Tiki::UserTikis` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TotalActiveTrustScore` (r:1 w:1)
|
||||
/// Proof: `Trust::TotalActiveTrustScore` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
|
||||
fn force_recalculate_trust_score() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `287`
|
||||
// Estimated: `3534`
|
||||
// Minimum execution time: 41_676_000 picoseconds.
|
||||
Weight::from_parts(51_361_000, 3534)
|
||||
.saturating_add(RocksDbWeight::get().reads(5_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2_u64))
|
||||
}
|
||||
/// Storage: `Trust::LastProcessedAccount` (r:1 w:1)
|
||||
/// Proof: `Trust::LastProcessedAccount` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `IdentityKyc::KycStatuses` (r:2 w:0)
|
||||
/// Proof: `IdentityKyc::KycStatuses` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TrustScores` (r:1 w:1)
|
||||
/// Proof: `Trust::TrustScores` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`)
|
||||
/// Storage: `StakingScore::StakingStartBlock` (r:1 w:0)
|
||||
/// Proof: `StakingScore::StakingStartBlock` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Referral::ReferralCount` (r:1 w:0)
|
||||
/// Proof: `Referral::ReferralCount` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Tiki::UserTikis` (r:1 w:0)
|
||||
/// Proof: `Tiki::UserTikis` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TotalActiveTrustScore` (r:1 w:1)
|
||||
/// Proof: `Trust::TotalActiveTrustScore` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::BatchUpdateInProgress` (r:0 w:1)
|
||||
/// Proof: `Trust::BatchUpdateInProgress` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`)
|
||||
fn update_all_trust_scores() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `338`
|
||||
// Estimated: `6038`
|
||||
// Minimum execution time: 57_062_000 picoseconds.
|
||||
Weight::from_parts(71_311_000, 6038)
|
||||
.saturating_add(RocksDbWeight::get().reads(8_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(4_u64))
|
||||
}
|
||||
/// Storage: `Trust::BatchUpdateInProgress` (r:1 w:1)
|
||||
/// Proof: `Trust::BatchUpdateInProgress` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::LastProcessedAccount` (r:1 w:1)
|
||||
/// Proof: `Trust::LastProcessedAccount` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `IdentityKyc::KycStatuses` (r:2 w:0)
|
||||
/// Proof: `IdentityKyc::KycStatuses` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TrustScores` (r:1 w:1)
|
||||
/// Proof: `Trust::TrustScores` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`)
|
||||
/// Storage: `StakingScore::StakingStartBlock` (r:1 w:0)
|
||||
/// Proof: `StakingScore::StakingStartBlock` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Referral::ReferralCount` (r:1 w:0)
|
||||
/// Proof: `Referral::ReferralCount` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Tiki::UserTikis` (r:1 w:0)
|
||||
/// Proof: `Tiki::UserTikis` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Trust::TotalActiveTrustScore` (r:1 w:1)
|
||||
/// Proof: `Trust::TotalActiveTrustScore` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
|
||||
fn periodic_trust_score_update() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `338`
|
||||
// Estimated: `6038`
|
||||
// Minimum execution time: 82_604_000 picoseconds.
|
||||
Weight::from_parts(88_810_000, 6038)
|
||||
.saturating_add(RocksDbWeight::get().reads(9_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(4_u64))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user