Refactoring Checkpoint: (WIP)

This commit is contained in:
2025-12-14 10:29:31 +03:00
parent 09735eb97a
commit c89d7cac55
1424 changed files with 6415 additions and 6064 deletions
@@ -0,0 +1,142 @@
//! Benchmarking setup for pezpallet-validator-pool
use super::*;
use pezframe_benchmarking::v2::*;
use pezframe_system::{pezpallet_prelude::BlockNumberFor, RawOrigin};
use pezsp_std::vec;
#[benchmarks]
mod benchmarks {
use super::*;
#[benchmark]
fn join_validator_pool() {
let caller: T::AccountId = whitelisted_caller();
let category = ValidatorPoolCategory::StakeValidator {
min_stake: T::MinStakeAmount::get(),
trust_threshold: 100u128, // Low threshold for benchmarking
};
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()), category.clone());
// Verify the validator was added
assert!(PoolMembers::<T>::contains_key(&caller));
assert!(PerformanceMetrics::<T>::contains_key(&caller));
}
#[benchmark]
fn leave_validator_pool() {
let caller: T::AccountId = whitelisted_caller();
let category = ValidatorPoolCategory::StakeValidator {
min_stake: T::MinStakeAmount::get(),
trust_threshold: 100u128,
};
PoolMembers::<T>::insert(&caller, &category);
PoolSize::<T>::put(1u32);
PerformanceMetrics::<T>::insert(&caller, ValidatorPerformance::default());
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
// Verify the validator was removed
assert!(!PoolMembers::<T>::contains_key(&caller));
assert!(!PerformanceMetrics::<T>::contains_key(&caller));
}
#[benchmark]
fn update_performance_metrics() {
let validator: T::AccountId = whitelisted_caller();
PerformanceMetrics::<T>::insert(&validator, ValidatorPerformance::default());
#[extrinsic_call]
_(
RawOrigin::Root,
validator.clone(),
100u32, // blocks_produced
10u32, // blocks_missed
500u32, // era_points
);
// Verify metrics were updated
let metrics = PerformanceMetrics::<T>::get(&validator);
assert_eq!(metrics.blocks_produced, 100);
}
#[benchmark]
fn force_new_era(p: Linear<4, 100>, // Pool size
) {
// Add validators to pool
for i in 0..p {
let validator: T::AccountId = account("validator", i, 0);
let category = match i % 3 {
0 => ValidatorPoolCategory::StakeValidator {
min_stake: T::MinStakeAmount::get(),
trust_threshold: 100u128,
},
1 => ValidatorPoolCategory::ParliamentaryValidator,
_ => ValidatorPoolCategory::MeritValidator {
special_tikis: vec![1u8].try_into().unwrap(),
community_threshold: 100u32,
},
};
PoolMembers::<T>::insert(&validator, &category);
let performance = ValidatorPerformance {
blocks_produced: 90,
blocks_missed: 10,
era_points: 500,
last_active_era: 0,
reputation_score: 90,
};
PerformanceMetrics::<T>::insert(&validator, performance);
}
PoolSize::<T>::put(p);
EraLength::<T>::put(BlockNumberFor::<T>::from(100u32));
#[extrinsic_call]
_(RawOrigin::Root);
// Verify new era was created
assert_eq!(CurrentEra::<T>::get(), 1);
assert!(CurrentValidatorSet::<T>::get().is_some());
}
#[benchmark]
fn update_category() {
let caller: T::AccountId = whitelisted_caller();
let initial_category = ValidatorPoolCategory::StakeValidator {
min_stake: T::MinStakeAmount::get(),
trust_threshold: 100u128,
};
PoolMembers::<T>::insert(&caller, &initial_category);
let new_category = ValidatorPoolCategory::ParliamentaryValidator;
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()), new_category.clone());
// Verify category was updated
assert_eq!(PoolMembers::<T>::get(&caller).unwrap(), new_category);
}
#[benchmark]
fn set_pool_parameters() {
let new_era_length = BlockNumberFor::<T>::from(200u32);
#[extrinsic_call]
_(RawOrigin::Root, new_era_length);
// Verify parameters were updated
assert_eq!(EraLength::<T>::get(), new_era_length);
}
impl_benchmark_test_suite!(ValidatorPool, crate::mock::new_test_ext(), crate::mock::Test);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,274 @@
use super::*;
use crate::{self as pezpallet_validator_pool, types::*};
use pezframe_support::{
construct_runtime, parameter_types,
traits::{ConstU32, Everything},
};
use pezframe_system as system;
use pezsp_core::H256;
use pezsp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
BuildStorage,
};
pub type AccountId = u64;
pub type Balance = u128;
pub type BlockNumber = u64;
// Configure a mock runtime to test the pallet.
// Note: We don't include pezpallet_session here because it requires complex Currency setup.
// We can test SessionManager trait implementation directly.
construct_runtime!(
pub enum Test {
System: pezframe_system,
Balances: pezpallet_balances,
ValidatorPool: pezpallet_validator_pool,
}
);
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const SS58Prefix: u8 = 42;
}
impl system::Config for Test {
type BaseCallFilter = Everything;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type RuntimeTask = ();
type Nonce = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = pezframe_system::mocking::MockBlock<Test>;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = BlockHashCount;
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pezpallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = SS58Prefix;
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
type ExtensionsWeightInfo = ();
type SingleBlockMigrations = ();
type MultiBlockMigrator = ();
type PreInherents = ();
type PostInherents = ();
type PostTransactions = ();
}
parameter_types! {
pub const ExistentialDeposit: Balance = 1;
pub const MaxLocks: u32 = 50;
pub const MaxReserves: u32 = 50;
}
impl pezpallet_balances::Config for Test {
type MaxLocks = MaxLocks;
type MaxReserves = MaxReserves;
type ReserveIdentifier = [u8; 8];
type Balance = Balance;
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type DoneSlashHandler = ();
}
// Mock Randomness
pub struct MockRandomness;
impl Randomness<H256, BlockNumber> for MockRandomness {
fn random(subject: &[u8]) -> (H256, BlockNumber) {
let mut hash = H256::zero();
// Simple deterministic randomness for testing
if !subject.is_empty() {
hash.as_mut()[0] = subject[0];
}
(hash, 1)
}
}
// Test implementations for trait dependencies
pub struct TestTrustProvider;
impl TrustScoreProvider<AccountId> for TestTrustProvider {
fn trust_score_of(who: &AccountId) -> u128 {
match who {
1..=15 => 1000, // Test users with high trust (threshold: 450)
_ => 100, // Others have insufficient trust
}
}
}
pub struct TestTikiProvider;
impl TikiScoreProvider<AccountId> for TestTikiProvider {
fn get_tiki_score(who: &AccountId) -> u32 {
match who {
1..=15 => 1, // Tüm test user'ları için tiki var
_ => 0,
}
}
}
pub struct TestReferralProvider;
impl ReferralProvider<AccountId> for TestReferralProvider {
fn get_referral_count(who: &AccountId) -> u32 {
match who {
1..=15 => 1000, // Tüm test user'ları için yüksek community support (threshold: 500)
_ => 600, // Diğerleri için de yeterli
}
}
}
pub struct TestPerwerdeProvider;
impl PerwerdeProvider<AccountId> for TestPerwerdeProvider {
fn get_perwerde_score(who: &AccountId) -> u32 {
match who {
1..=15 => 100, // Tüm test user'ları için perwerde var
_ => 50,
}
}
}
parameter_types! {
pub const MaxValidators: u32 = 21;
pub const MaxPoolSize: u32 = 500;
pub const MinStakeAmount: u128 = 1000;
}
// Mock WeightInfo implementation
pub struct MockWeightInfo;
impl crate::WeightInfo for MockWeightInfo {
fn join_validator_pool() -> pezframe_support::weights::Weight {
pezframe_support::weights::Weight::from_parts(10_000, 0)
}
fn leave_validator_pool() -> pezframe_support::weights::Weight {
pezframe_support::weights::Weight::from_parts(10_000, 0)
}
fn update_performance_metrics() -> pezframe_support::weights::Weight {
pezframe_support::weights::Weight::from_parts(10_000, 0)
}
fn force_new_era() -> pezframe_support::weights::Weight {
pezframe_support::weights::Weight::from_parts(50_000, 0)
}
fn update_category() -> pezframe_support::weights::Weight {
pezframe_support::weights::Weight::from_parts(10_000, 0)
}
fn set_pool_parameters() -> pezframe_support::weights::Weight {
pezframe_support::weights::Weight::from_parts(10_000, 0)
}
}
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = MockWeightInfo;
type Randomness = MockRandomness;
type TrustSource = TestTrustProvider;
type TikiSource = TestTikiProvider;
type ReferralSource = TestReferralProvider;
type PerwerdeSource = TestPerwerdeProvider;
type PoolManagerOrigin = pezframe_system::EnsureRoot<AccountId>;
type MaxValidators = MaxValidators;
type MaxPoolSize = MaxPoolSize;
type MinStakeAmount = MinStakeAmount;
}
// Build genesis storage according to the mock runtime.
pub fn new_test_ext() -> pezsp_io::TestExternalities {
new_test_ext_with_mode(OperationMode::Active)
}
// Build genesis storage with specific operation mode
pub fn new_test_ext_with_mode(mode: OperationMode) -> pezsp_io::TestExternalities {
let mut storage = system::GenesisConfig::<Test>::default().build_storage().unwrap();
// Initialize balances - Fixed genesis config with correct type
pezpallet_balances::GenesisConfig::<Test> {
balances: vec![
(1, 10000),
(2, 8000),
(3, 6000),
(4, 4000),
(5, 2000),
(6, 5000),
(7, 5000),
(8, 5000),
(9, 5000),
(10, 5000),
],
dev_accounts: None,
}
.assimilate_storage(&mut storage)
.unwrap();
// Initialize validator pool with genesis config
pezpallet_validator_pool::GenesisConfig::<Test> {
operation_mode: mode,
era_length: 100,
initial_pool_members: vec![],
}
.assimilate_storage(&mut storage)
.unwrap();
let mut ext = pezsp_io::TestExternalities::new(storage);
ext.execute_with(|| {
System::set_block_number(1);
});
ext
}
// Build genesis storage for shadow mode testing
pub fn new_test_ext_shadow_mode() -> pezsp_io::TestExternalities {
new_test_ext_with_mode(OperationMode::Shadow)
}
// Helper functions for tests
pub fn run_to_block(n: u64) {
while System::block_number() < n {
if System::block_number() > 1 {
ValidatorPool::on_finalize(System::block_number());
System::on_finalize(System::block_number());
}
System::set_block_number(System::block_number() + 1);
System::on_initialize(System::block_number());
ValidatorPool::on_initialize(System::block_number());
}
}
pub fn advance_era() {
let current_era_start = ValidatorPool::era_start();
let era_length = ValidatorPool::era_length();
run_to_block(current_era_start + era_length + 1);
}
// Create test categories
pub fn stake_validator_category() -> ValidatorPoolCategory {
ValidatorPoolCategory::StakeValidator { min_stake: 1000, trust_threshold: 450 }
}
pub fn parliamentary_validator_category() -> ValidatorPoolCategory {
ValidatorPoolCategory::ParliamentaryValidator
}
pub fn merit_validator_category() -> ValidatorPoolCategory {
ValidatorPoolCategory::MeritValidator {
special_tikis: vec![1u8].try_into().unwrap(), // Mock tiki type
community_threshold: 500,
}
}
@@ -0,0 +1,799 @@
use super::*;
use crate::{mock::*, types::OperationMode};
use pezframe_support::{assert_noop, assert_ok};
// Import SessionManager trait for testing
use pezpallet_session::SessionManager;
#[test]
fn join_validator_pool_works() {
new_test_ext().execute_with(|| {
// User 1 has high trust (800) and tiki score (1)
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
// Check storage
assert!(ValidatorPool::pool_members(1).is_some());
assert_eq!(ValidatorPool::pool_size(), 1);
// Check performance metrics initialized
let metrics = ValidatorPool::performance_metrics(1);
assert_eq!(metrics.reputation_score, 100);
assert_eq!(metrics.blocks_produced, 0);
});
}
#[test]
fn join_validator_pool_fails_insufficient_trust() {
new_test_ext().execute_with(|| {
assert_noop!(
ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(99),
stake_validator_category()
),
Error::<Test>::InsufficientTrustScore
);
});
}
#[test]
fn join_validator_pool_fails_already_in_pool() {
new_test_ext().execute_with(|| {
// First join succeeds
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
// Second join fails
assert_noop!(
ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
),
Error::<Test>::AlreadyInPool
);
});
}
#[test]
fn leave_validator_pool_works() {
new_test_ext().execute_with(|| {
// Join first
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
assert_eq!(ValidatorPool::pool_size(), 1);
// Leave pool
assert_ok!(ValidatorPool::leave_validator_pool(RuntimeOrigin::signed(1)));
// Check storage cleaned up
assert!(ValidatorPool::pool_members(1).is_none());
assert_eq!(ValidatorPool::pool_size(), 0);
// Performance metrics should be removed
let metrics = ValidatorPool::performance_metrics(1);
assert_eq!(metrics.reputation_score, 0); // Default value
});
}
#[test]
fn leave_validator_pool_fails_not_in_pool() {
new_test_ext().execute_with(|| {
assert_noop!(
ValidatorPool::leave_validator_pool(RuntimeOrigin::signed(1)),
Error::<Test>::NotInPool
);
});
}
#[test]
fn parliamentary_validator_category_validation() {
new_test_ext().execute_with(|| {
// User 1 has tiki score, should succeed
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
parliamentary_validator_category()
));
// User 16 has no tiki score, should fail
assert_noop!(
ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(16),
parliamentary_validator_category()
),
Error::<Test>::MissingRequiredTiki
);
});
}
#[test]
fn merit_validator_category_validation() {
new_test_ext().execute_with(|| {
// User 1 has both tiki score (1) and high community support (1000)
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
merit_validator_category()
));
// User 16 has no tiki score
assert_noop!(
ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(16),
merit_validator_category()
),
Error::<Test>::MissingRequiredTiki
);
});
}
#[test]
fn update_category_works() {
new_test_ext().execute_with(|| {
// Join as stake validator
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
// Update to parliamentary validator
assert_ok!(ValidatorPool::update_category(
RuntimeOrigin::signed(1),
parliamentary_validator_category()
));
// Check category updated
let category = ValidatorPool::pool_members(1).unwrap();
assert!(matches!(category, ValidatorPoolCategory::ParliamentaryValidator));
});
}
#[test]
fn force_new_era_works() {
new_test_ext().execute_with(|| {
// Add validators to pool (at least 4 for BFT)
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(2),
parliamentary_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(3),
merit_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(4),
stake_validator_category()
));
let initial_era = ValidatorPool::current_era();
// Force new era
assert_ok!(ValidatorPool::force_new_era(RuntimeOrigin::root()));
// Check era incremented
assert_eq!(ValidatorPool::current_era(), initial_era + 1);
// Check validator set exists
assert!(ValidatorPool::current_validator_set().is_some());
});
}
#[test]
fn automatic_era_transition_works() {
new_test_ext().execute_with(|| {
// Add validators
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(2),
parliamentary_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(3),
stake_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(4),
stake_validator_category()
));
let initial_era = ValidatorPool::current_era();
let era_start = ValidatorPool::era_start();
let era_length = ValidatorPool::era_length();
// Advance to trigger era transition
run_to_block(era_start + era_length);
// Era should have automatically transitioned
assert_eq!(ValidatorPool::current_era(), initial_era + 1);
});
}
#[test]
fn validator_selection_respects_constraints() {
new_test_ext().execute_with(|| {
// Add different types of validators
for i in 1..=10 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
// Force era to trigger selection
assert_ok!(ValidatorPool::force_new_era(RuntimeOrigin::root()));
let validator_set = ValidatorPool::current_validator_set().unwrap();
assert!(!validator_set.stake_validators.is_empty());
assert!(validator_set.total_count() <= 21);
});
}
#[test]
fn performance_metrics_update_works() {
new_test_ext().execute_with(|| {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
assert_ok!(ValidatorPool::update_performance_metrics(
RuntimeOrigin::root(),
1,
100,
10,
500
));
let metrics = ValidatorPool::performance_metrics(1);
assert_eq!(metrics.blocks_produced, 100);
assert_eq!(metrics.blocks_missed, 10);
assert_eq!(metrics.era_points, 500);
assert_eq!(metrics.reputation_score, 90);
});
}
#[test]
fn poor_performance_excludes_from_selection() {
new_test_ext().execute_with(|| {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
assert_ok!(ValidatorPool::update_performance_metrics(
RuntimeOrigin::root(),
1,
30,
70,
100
));
let metrics = ValidatorPool::performance_metrics(1);
assert_eq!(metrics.reputation_score, 30);
// Add other good performers
for i in 2..=5 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
assert_ok!(ValidatorPool::force_new_era(RuntimeOrigin::root()));
let validator_set = ValidatorPool::current_validator_set().unwrap();
assert!(!validator_set.all_validators().contains(&1));
assert!(validator_set.all_validators().contains(&2));
});
}
#[test]
fn rotation_rule_works() {
new_test_ext().execute_with(|| {
// Simply test that multiple validators can be added and pool works
for i in 1..=5 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
// Test that pool size is correct
assert_eq!(ValidatorPool::pool_size(), 5);
// Test that we can remove validators
assert_ok!(ValidatorPool::leave_validator_pool(RuntimeOrigin::signed(1)));
assert_eq!(ValidatorPool::pool_size(), 4);
});
}
#[test]
fn pool_size_limit_enforced() {
new_test_ext().execute_with(|| {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
assert_eq!(ValidatorPool::pool_size(), 1);
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(2),
parliamentary_validator_category()
));
assert_eq!(ValidatorPool::pool_size(), 2);
assert_ok!(ValidatorPool::leave_validator_pool(RuntimeOrigin::signed(1)));
assert_eq!(ValidatorPool::pool_size(), 1);
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(3),
merit_validator_category()
));
assert_eq!(ValidatorPool::pool_size(), 2);
});
}
#[test]
fn set_pool_parameters_works() {
new_test_ext().execute_with(|| {
assert_noop!(
ValidatorPool::set_pool_parameters(RuntimeOrigin::signed(1), 200),
pezsp_runtime::DispatchError::BadOrigin
);
assert_ok!(ValidatorPool::set_pool_parameters(RuntimeOrigin::root(), 200));
assert_eq!(ValidatorPool::era_length(), 200);
});
}
#[test]
fn session_manager_integration_works() {
new_test_ext().execute_with(|| {
for i in 1..=5 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
assert_ok!(ValidatorPool::force_new_era(RuntimeOrigin::root()));
let validators = <ValidatorPool as SessionManager<u64>>::new_session(1);
assert!(validators.is_some());
let validator_list = validators.unwrap();
assert!(!validator_list.is_empty());
});
}
#[test]
fn validator_set_distribution_works() {
new_test_ext().execute_with(|| {
for i in 1..=15 {
let category = match i {
1..=10 => stake_validator_category(),
11..=13 => parliamentary_validator_category(),
_ => merit_validator_category(),
};
assert_ok!(ValidatorPool::join_validator_pool(RuntimeOrigin::signed(i), category));
}
assert_ok!(ValidatorPool::force_new_era(RuntimeOrigin::root()));
let validator_set = ValidatorPool::current_validator_set().unwrap();
assert!(validator_set.total_count() > 0);
assert!(validator_set.total_count() <= 21);
assert!(!validator_set.stake_validators.is_empty());
assert!(!validator_set.parliamentary_validators.is_empty());
assert!(!validator_set.merit_validators.is_empty());
});
}
#[test]
fn events_are_emitted() {
new_test_ext().execute_with(|| {
System::set_block_number(1);
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
let events = System::events();
assert!(events.iter().any(|event| matches!(
event.event,
RuntimeEvent::ValidatorPool(crate::Event::ValidatorJoinedPool { .. })
)));
System::reset_events();
assert_ok!(ValidatorPool::leave_validator_pool(RuntimeOrigin::signed(1)));
let events = System::events();
assert!(events.iter().any(|event| matches!(
event.event,
RuntimeEvent::ValidatorPool(crate::Event::ValidatorLeftPool { .. })
)));
});
}
#[test]
fn minimum_validator_count_enforced() {
new_test_ext().execute_with(|| {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(2),
parliamentary_validator_category()
));
assert_noop!(
ValidatorPool::force_new_era(RuntimeOrigin::root()),
Error::<Test>::NotEnoughValidators
);
});
}
#[test]
fn complex_era_transition_scenario() {
new_test_ext().execute_with(|| {
// Test validator addition with different categories
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(2),
parliamentary_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(3),
merit_validator_category()
));
// Test performance metrics update
assert_ok!(ValidatorPool::update_performance_metrics(
RuntimeOrigin::root(),
1,
90,
10,
500
));
let metrics = ValidatorPool::performance_metrics(1);
assert_eq!(metrics.reputation_score, 90);
// Test category update
assert_ok!(ValidatorPool::update_category(
RuntimeOrigin::signed(1),
parliamentary_validator_category()
));
// Test pool size
assert_eq!(ValidatorPool::pool_size(), 3);
});
}
// ============================================================================
// SHADOW MODE TESTS
// ============================================================================
#[test]
fn genesis_sets_operation_mode() {
// Test Active mode genesis
new_test_ext().execute_with(|| {
assert_eq!(ValidatorPool::operation_mode(), OperationMode::Active);
});
// Test Shadow mode genesis
new_test_ext_shadow_mode().execute_with(|| {
assert_eq!(ValidatorPool::operation_mode(), OperationMode::Shadow);
// Shadow mode should track activation block
assert!(ValidatorPool::shadow_mode_since().is_some());
});
}
#[test]
fn set_operation_mode_works() {
new_test_ext().execute_with(|| {
// Start in Active mode
assert_eq!(ValidatorPool::operation_mode(), OperationMode::Active);
// Switch to Shadow mode
assert_ok!(ValidatorPool::set_operation_mode(RuntimeOrigin::root(), OperationMode::Shadow));
assert_eq!(ValidatorPool::operation_mode(), OperationMode::Shadow);
// Switch back to Active mode
assert_ok!(ValidatorPool::set_operation_mode(RuntimeOrigin::root(), OperationMode::Active));
assert_eq!(ValidatorPool::operation_mode(), OperationMode::Active);
});
}
#[test]
fn set_operation_mode_fails_same_mode() {
new_test_ext().execute_with(|| {
// Already in Active mode
assert_noop!(
ValidatorPool::set_operation_mode(RuntimeOrigin::root(), OperationMode::Active),
Error::<Test>::AlreadyInActiveMode
);
});
new_test_ext_shadow_mode().execute_with(|| {
// Already in Shadow mode
assert_noop!(
ValidatorPool::set_operation_mode(RuntimeOrigin::root(), OperationMode::Shadow),
Error::<Test>::AlreadyInShadowMode
);
});
}
#[test]
fn set_operation_mode_requires_root() {
new_test_ext().execute_with(|| {
assert_noop!(
ValidatorPool::set_operation_mode(RuntimeOrigin::signed(1), OperationMode::Shadow),
pezsp_runtime::DispatchError::BadOrigin
);
});
}
#[test]
fn shadow_mode_session_manager_returns_none() {
new_test_ext_shadow_mode().execute_with(|| {
// Add validators
for i in 1..=5 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
// In shadow mode, new_session should return None
let validators = <ValidatorPool as SessionManager<u64>>::new_session(1);
assert!(validators.is_none());
// But shadow validator set should be stored
assert!(ValidatorPool::shadow_validator_set().is_some());
});
}
#[test]
fn active_mode_session_manager_returns_validators() {
new_test_ext().execute_with(|| {
// Add validators
for i in 1..=5 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
// Force first era to get a validator set
assert_ok!(ValidatorPool::force_new_era(RuntimeOrigin::root()));
// In active mode, new_session should return validators
let validators = <ValidatorPool as SessionManager<u64>>::new_session(2);
assert!(validators.is_some());
assert!(!validators.unwrap().is_empty());
});
}
#[test]
fn record_npos_validators_works() {
new_test_ext_shadow_mode().execute_with(|| {
// Add validators to pool
for i in 1..=5 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
// Trigger shadow selection
let _ = <ValidatorPool as SessionManager<u64>>::new_session(1);
// Record NPoS validators
let npos_validators = vec![1u64, 2, 3, 6, 7];
assert_ok!(ValidatorPool::record_npos_validators(RuntimeOrigin::root(), npos_validators));
// Check NPoS set is stored
assert!(!ValidatorPool::npos_validator_set().is_empty());
});
}
#[test]
fn record_npos_validators_fails_in_active_mode() {
new_test_ext().execute_with(|| {
let npos_validators = vec![1u64, 2, 3];
assert_noop!(
ValidatorPool::record_npos_validators(RuntimeOrigin::root(), npos_validators),
Error::<Test>::ShadowModeNotEnabled
);
});
}
#[test]
fn shadow_comparison_recorded() {
new_test_ext_shadow_mode().execute_with(|| {
// Add validators to pool
for i in 1..=10 {
let category = if i <= 5 {
stake_validator_category()
} else if i <= 7 {
parliamentary_validator_category()
} else {
merit_validator_category()
};
assert_ok!(ValidatorPool::join_validator_pool(RuntimeOrigin::signed(i), category));
}
// Trigger shadow selection
let _ = <ValidatorPool as SessionManager<u64>>::new_session(1);
// Record NPoS validators (some overlap, some different)
let npos_validators = vec![1u64, 2, 3, 11, 12];
assert_ok!(ValidatorPool::record_npos_validators(RuntimeOrigin::root(), npos_validators));
// Check comparison was recorded
let comparison = ValidatorPool::shadow_comparison();
assert!(comparison.is_some());
let comp = comparison.unwrap();
assert!(comp.overlap_count > 0 || comp.tnpos_only.len() > 0 || comp.npos_only.len() > 0);
});
}
#[test]
fn cumulative_statistics_updated() {
new_test_ext_shadow_mode().execute_with(|| {
// Add validators
for i in 1..=5 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
// Trigger shadow selection
let _ = <ValidatorPool as SessionManager<u64>>::new_session(1);
// Record NPoS validators
let npos_validators = vec![1u64, 2, 6, 7, 8];
assert_ok!(ValidatorPool::record_npos_validators(RuntimeOrigin::root(), npos_validators));
// Check cumulative stats were updated
let stats = ValidatorPool::shadow_statistics();
assert_eq!(stats.eras_analyzed, 1);
});
}
#[test]
fn era_analysis_data_stored() {
new_test_ext_shadow_mode().execute_with(|| {
// Add validators
for i in 1..=5 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
// Trigger shadow selection
let _ = <ValidatorPool as SessionManager<u64>>::new_session(1);
// Record NPoS validators
let npos_validators = vec![1u64, 2, 3, 4, 5];
assert_ok!(ValidatorPool::record_npos_validators(RuntimeOrigin::root(), npos_validators));
// Check era analysis was stored
let era = ValidatorPool::current_era();
let analysis = ValidatorPool::era_analysis(era);
assert!(analysis.is_some());
});
}
#[test]
fn category_distribution_tracked() {
new_test_ext_shadow_mode().execute_with(|| {
// Add different category validators
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(1),
stake_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(2),
stake_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(3),
parliamentary_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(4),
merit_validator_category()
));
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(5),
stake_validator_category()
));
// Trigger shadow selection
let _ = <ValidatorPool as SessionManager<u64>>::new_session(1);
// Record NPoS validators
assert_ok!(ValidatorPool::record_npos_validators(
RuntimeOrigin::root(),
vec![1u64, 2, 3, 4, 5]
));
// Check category distribution was recorded
let era = ValidatorPool::current_era();
let distribution = ValidatorPool::category_distribution(era);
assert!(distribution.is_some());
let dist = distribution.unwrap();
assert!(dist.target_stake > 0);
});
}
#[test]
fn record_era_end_stats_works() {
new_test_ext_shadow_mode().execute_with(|| {
// Setup validators and trigger comparison
for i in 1..=5 {
assert_ok!(ValidatorPool::join_validator_pool(
RuntimeOrigin::signed(i),
stake_validator_category()
));
}
let _ = <ValidatorPool as SessionManager<u64>>::new_session(1);
assert_ok!(ValidatorPool::record_npos_validators(
RuntimeOrigin::root(),
vec![1u64, 2, 3, 4, 5]
));
// Record era end stats
let era = ValidatorPool::current_era();
assert_ok!(ValidatorPool::record_era_end_stats(
RuntimeOrigin::root(),
era,
950, // blocks produced
50 // blocks missed
));
// Check era analysis was updated
let analysis = ValidatorPool::era_analysis(era);
assert!(analysis.is_some());
let a = analysis.unwrap();
assert_eq!(a.blocks_produced, 950);
assert_eq!(a.blocks_missed, 50);
});
}
#[test]
fn operation_mode_change_emits_event() {
new_test_ext().execute_with(|| {
System::set_block_number(1);
System::reset_events();
assert_ok!(ValidatorPool::set_operation_mode(RuntimeOrigin::root(), OperationMode::Shadow));
let events = System::events();
assert!(events.iter().any(|event| matches!(
event.event,
RuntimeEvent::ValidatorPool(crate::Event::OperationModeChanged { .. })
)));
});
}
#[test]
fn shadow_mode_tracks_activation_block() {
new_test_ext().execute_with(|| {
System::set_block_number(100);
// Switch to shadow mode
assert_ok!(ValidatorPool::set_operation_mode(RuntimeOrigin::root(), OperationMode::Shadow));
// Check activation block is tracked
let since = ValidatorPool::shadow_mode_since();
assert!(since.is_some());
assert_eq!(since.unwrap(), 100);
});
}
@@ -0,0 +1,305 @@
extern crate alloc;
use alloc::vec::Vec;
use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
use pezframe_support::{traits::ConstU32, BoundedVec};
use scale_info::TypeInfo;
use pezsp_runtime::RuntimeDebug;
/// Types of validators in the pool
#[derive(
Encode,
Decode,
DecodeWithMemTracking,
Clone,
PartialEq,
Eq,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
serde::Serialize,
serde::Deserialize,
)]
#[codec(mel_bound())]
pub enum ValidatorPoolCategory {
/// Stake-based validators (high stake + trust score)
StakeValidator { min_stake: u128, trust_threshold: u128 },
/// Parliamentary validators (elected parliament members)
ParliamentaryValidator,
/// Merit-based validators (special Tikis + community support)
MeritValidator {
special_tikis: BoundedVec<u8, ConstU32<5>>, // Tiki types they hold
community_threshold: u32, // Minimum referral count
},
}
/// Performance metrics for a validator
#[derive(
Encode,
Decode,
DecodeWithMemTracking,
Clone,
PartialEq,
Eq,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
Default,
)]
#[codec(mel_bound())]
pub struct ValidatorPerformance {
/// Total blocks produced
pub blocks_produced: u32,
/// Total blocks missed
pub blocks_missed: u32,
/// Era points earned
pub era_points: u32,
/// Last era when this validator was active
pub last_active_era: u32,
/// Reputation score (0-100)
pub reputation_score: u8,
}
/// Current validator set for an era
#[derive(
Encode,
Decode,
DecodeWithMemTracking,
Clone,
PartialEq,
Eq,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
)]
#[codec(mel_bound())]
pub struct ValidatorSet<AccountId>
where
AccountId: Encode + Decode + DecodeWithMemTracking + Clone + PartialEq + Eq + MaxEncodedLen,
{
/// Era index
pub era_index: u32,
/// Stake-based validators (target: 10)
pub stake_validators: BoundedVec<AccountId, ConstU32<10>>,
/// Parliamentary validators (target: 6)
pub parliamentary_validators: BoundedVec<AccountId, ConstU32<6>>,
/// Merit-based validators (target: 5)
pub merit_validators: BoundedVec<AccountId, ConstU32<5>>,
}
impl<AccountId> ValidatorSet<AccountId>
where
AccountId: Encode + Decode + DecodeWithMemTracking + Clone + PartialEq + Eq + MaxEncodedLen,
{
/// Get all validators in the set
pub fn all_validators(&self) -> Vec<AccountId> {
let mut all = Vec::new();
all.extend(self.stake_validators.iter().cloned());
all.extend(self.parliamentary_validators.iter().cloned());
all.extend(self.merit_validators.iter().cloned());
all
}
/// Get total validator count
pub fn total_count(&self) -> u32 {
self.stake_validators.len() as u32 +
self.parliamentary_validators.len() as u32 +
self.merit_validators.len() as u32
}
}
/// Trait for referral system integration
pub trait ReferralProvider<AccountId> {
/// Get referral count for an account
fn get_referral_count(who: &AccountId) -> u32;
}
/// Trait for Perwerde system integration
pub trait PerwerdeProvider<AccountId> {
/// Get Perwerde score for an account
fn get_perwerde_score(who: &AccountId) -> u32;
}
/// Default implementation for tests
impl<AccountId> ReferralProvider<AccountId> for () {
fn get_referral_count(_who: &AccountId) -> u32 {
0
}
}
impl<AccountId> PerwerdeProvider<AccountId> for () {
fn get_perwerde_score(_who: &AccountId) -> u32 {
0
}
}
// ============================================================================
// SHADOW MODE TYPES
// ============================================================================
/// Operation mode for the validator pool
#[derive(
Encode,
Decode,
DecodeWithMemTracking,
Clone,
Copy,
PartialEq,
Eq,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
Default,
serde::Serialize,
serde::Deserialize,
)]
pub enum OperationMode {
/// Shadow mode: TNPoS runs in parallel but doesn't control consensus
/// NPoS remains the authority, TNPoS results are recorded for comparison
#[default]
Shadow,
/// Active mode: TNPoS directly controls validator selection
/// Used on Zagros testnet and after full transition
Active,
}
/// Shadow mode comparison result for a single era
#[derive(
Encode,
Decode,
DecodeWithMemTracking,
Clone,
PartialEq,
Eq,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
Default,
)]
#[codec(mel_bound())]
pub struct ShadowComparison<AccountId>
where
AccountId: Encode + Decode + DecodeWithMemTracking + Clone + PartialEq + Eq + MaxEncodedLen,
{
/// Era when this comparison was made
pub era_index: u32,
/// Number of validators that appear in both NPoS and TNPoS selections
pub overlap_count: u32,
/// Validators selected by TNPoS but not by NPoS
pub tnpos_only: BoundedVec<AccountId, ConstU32<21>>,
/// Validators selected by NPoS but not by TNPoS
pub npos_only: BoundedVec<AccountId, ConstU32<21>>,
/// TNPoS selection would have included more stake validators
pub stake_diff: i32,
/// TNPoS selection would have included more parliamentary validators
pub parliamentary_diff: i32,
/// TNPoS selection would have included more merit validators
pub merit_diff: i32,
}
/// Cumulative shadow mode statistics across multiple eras
#[derive(
Encode,
Decode,
DecodeWithMemTracking,
Clone,
PartialEq,
Eq,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
Default,
)]
#[codec(mel_bound())]
pub struct ShadowStatistics {
/// Total number of eras analyzed
pub eras_analyzed: u32,
/// Total overlapping validators across all eras
pub total_overlap: u32,
/// Total TNPoS-only selections across all eras
pub total_tnpos_only: u32,
/// Total NPoS-only selections across all eras
pub total_npos_only: u32,
/// Average overlap percentage (stored as basis points, e.g., 5000 = 50%)
pub avg_overlap_bps: u32,
/// Number of eras where TNPoS would have performed better (based on block production)
pub tnpos_better_eras: u32,
/// Number of eras where NPoS performed better
pub npos_better_eras: u32,
/// Total blocks that would have been produced by TNPoS selections
pub tnpos_projected_blocks: u64,
/// Total blocks actually produced by NPoS selections
pub npos_actual_blocks: u64,
/// Eras where TNPoS had higher stake representation
pub higher_stake_eras: u32,
/// Eras where TNPoS had higher trust representation
pub higher_trust_eras: u32,
}
/// Detailed per-era shadow analysis data
#[derive(
Encode,
Decode,
DecodeWithMemTracking,
Clone,
PartialEq,
Eq,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
Default,
)]
#[codec(mel_bound())]
pub struct EraAnalysis {
/// Era index
pub era_index: u32,
/// Block number when analysis was recorded
pub recorded_at_block: u32,
/// Total stake of TNPoS selected validators
pub tnpos_total_stake: u128,
/// Total stake of NPoS selected validators
pub npos_total_stake: u128,
/// Average trust score of TNPoS selected validators
pub tnpos_avg_trust: u32,
/// Average trust score of NPoS selected validators
pub npos_avg_trust: u32,
/// Number of stake validators in TNPoS selection
pub tnpos_stake_count: u8,
/// Number of parliamentary validators in TNPoS selection
pub tnpos_parliamentary_count: u8,
/// Number of merit validators in TNPoS selection
pub tnpos_merit_count: u8,
/// Blocks produced this era (filled at era end)
pub blocks_produced: u32,
/// Blocks missed this era (filled at era end)
pub blocks_missed: u32,
}
/// Category distribution snapshot
#[derive(
Encode,
Decode,
DecodeWithMemTracking,
Clone,
PartialEq,
Eq,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
Default,
)]
#[codec(mel_bound())]
pub struct CategoryDistribution {
/// Stake validators count
pub stake: u8,
/// Parliamentary validators count
pub parliamentary: u8,
/// Merit validators count
pub merit: u8,
/// Target stake count
pub target_stake: u8,
/// Target parliamentary count
pub target_parliamentary: u8,
/// Target merit count
pub target_merit: u8,
}
@@ -0,0 +1,252 @@
// 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_validator_pool`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-11-30, 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: `Some("dev")`, DB CACHE: `1024`
// Executed Command:
// /home/mamostehp/Pezkuwi-SDK/target/release/pezkuwi
// benchmark
// pallet
// --chain=dev
// --pallet=pezpallet_validator_pool
// --extrinsic=*
// --steps=50
// --repeat=20
// --output=/home/mamostehp/Pezkuwi-SDK/pezkuwi/pallets/validator-pool/src/weights.rs
// --template=/home/mamostehp/Pezkuwi-SDK/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;
use crate::WeightInfo;
/// Weights for `pezpallet_validator_pool` using the Bizinikiwi node and recommended hardware.
pub struct BizinikiwiWeight<T>(PhantomData<T>);
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
/// Storage: `ValidatorPool::PoolMembers` (r:1 w:1)
/// Proof: `ValidatorPool::PoolMembers` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PoolSize` (r:1 w:1)
/// Proof: `ValidatorPool::PoolSize` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::CurrentEra` (r:1 w:0)
/// Proof: `ValidatorPool::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PerformanceMetrics` (r:0 w:1)
/// Proof: `ValidatorPool::PerformanceMetrics` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
fn join_validator_pool() -> Weight {
// Proof Size summary in bytes:
// Measured: `110`
// Estimated: `3546`
// Minimum execution time: 16_865_000 picoseconds.
Weight::from_parts(18_041_000, 3546)
.saturating_add(T::DbWeight::get().reads(3_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `ValidatorPool::PoolMembers` (r:1 w:1)
/// Proof: `ValidatorPool::PoolMembers` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PoolSize` (r:1 w:1)
/// Proof: `ValidatorPool::PoolSize` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PerformanceMetrics` (r:0 w:1)
/// Proof: `ValidatorPool::PerformanceMetrics` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::SelectionHistory` (r:0 w:1)
/// Proof: `ValidatorPool::SelectionHistory` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
fn leave_validator_pool() -> Weight {
// Proof Size summary in bytes:
// Measured: `267`
// Estimated: `3546`
// Minimum execution time: 18_228_000 picoseconds.
Weight::from_parts(18_832_000, 3546)
.saturating_add(T::DbWeight::get().reads(2_u64))
.saturating_add(T::DbWeight::get().writes(4_u64))
}
/// Storage: `ValidatorPool::PerformanceMetrics` (r:1 w:1)
/// Proof: `ValidatorPool::PerformanceMetrics` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::CurrentEra` (r:1 w:0)
/// Proof: `ValidatorPool::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn update_performance_metrics() -> Weight {
// Proof Size summary in bytes:
// Measured: `197`
// Estimated: `3530`
// Minimum execution time: 15_814_000 picoseconds.
Weight::from_parts(16_553_000, 3530)
.saturating_add(T::DbWeight::get().reads(2_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `ValidatorPool::CurrentEra` (r:1 w:1)
/// Proof: `ValidatorPool::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Babe::NextRandomness` (r:1 w:0)
/// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
/// Storage: `Babe::EpochStart` (r:1 w:0)
/// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PoolMembers` (r:101 w:0)
/// Proof: `ValidatorPool::PoolMembers` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::SelectionHistory` (r:100 w:21)
/// Proof: `ValidatorPool::SelectionHistory` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PerformanceMetrics` (r:100 w:0)
/// Proof: `ValidatorPool::PerformanceMetrics` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::CurrentValidatorSet` (r:0 w:1)
/// Proof: `ValidatorPool::CurrentValidatorSet` (`max_values`: Some(1), `max_size`: Some(679), added: 1174, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::EraStart` (r:0 w:1)
/// Proof: `ValidatorPool::EraStart` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// The range of component `p` is `[4, 100]`.
fn force_new_era(p: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `354 + p * (139 ±0)`
// Estimated: `3546 + p * (2556 ±0)`
// Minimum execution time: 68_990_000 picoseconds.
Weight::from_parts(55_692_892, 3546)
// Standard Error: 19_014
.saturating_add(Weight::from_parts(9_817_847, 0).saturating_mul(p.into()))
.saturating_add(T::DbWeight::get().reads(4_u64))
.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into())))
.saturating_add(T::DbWeight::get().writes(17_u64))
.saturating_add(Weight::from_parts(0, 2556).saturating_mul(p.into()))
}
/// Storage: `ValidatorPool::PoolMembers` (r:1 w:1)
/// Proof: `ValidatorPool::PoolMembers` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
fn update_category() -> Weight {
// Proof Size summary in bytes:
// Measured: `215`
// Estimated: `3546`
// Minimum execution time: 15_344_000 picoseconds.
Weight::from_parts(16_181_000, 3546)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `ValidatorPool::EraLength` (r:0 w:1)
/// Proof: `ValidatorPool::EraLength` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn set_pool_parameters() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 6_159_000 picoseconds.
Weight::from_parts(6_422_000, 0)
.saturating_add(T::DbWeight::get().writes(1_u64))
}
}
// For backwards compatibility and tests.
impl WeightInfo for () {
/// Storage: `ValidatorPool::PoolMembers` (r:1 w:1)
/// Proof: `ValidatorPool::PoolMembers` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PoolSize` (r:1 w:1)
/// Proof: `ValidatorPool::PoolSize` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::CurrentEra` (r:1 w:0)
/// Proof: `ValidatorPool::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PerformanceMetrics` (r:0 w:1)
/// Proof: `ValidatorPool::PerformanceMetrics` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
fn join_validator_pool() -> Weight {
// Proof Size summary in bytes:
// Measured: `110`
// Estimated: `3546`
// Minimum execution time: 16_865_000 picoseconds.
Weight::from_parts(18_041_000, 3546)
.saturating_add(RocksDbWeight::get().reads(3_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
/// Storage: `ValidatorPool::PoolMembers` (r:1 w:1)
/// Proof: `ValidatorPool::PoolMembers` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PoolSize` (r:1 w:1)
/// Proof: `ValidatorPool::PoolSize` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PerformanceMetrics` (r:0 w:1)
/// Proof: `ValidatorPool::PerformanceMetrics` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::SelectionHistory` (r:0 w:1)
/// Proof: `ValidatorPool::SelectionHistory` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
fn leave_validator_pool() -> Weight {
// Proof Size summary in bytes:
// Measured: `267`
// Estimated: `3546`
// Minimum execution time: 18_228_000 picoseconds.
Weight::from_parts(18_832_000, 3546)
.saturating_add(RocksDbWeight::get().reads(2_u64))
.saturating_add(RocksDbWeight::get().writes(4_u64))
}
/// Storage: `ValidatorPool::PerformanceMetrics` (r:1 w:1)
/// Proof: `ValidatorPool::PerformanceMetrics` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::CurrentEra` (r:1 w:0)
/// Proof: `ValidatorPool::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn update_performance_metrics() -> Weight {
// Proof Size summary in bytes:
// Measured: `197`
// Estimated: `3530`
// Minimum execution time: 15_814_000 picoseconds.
Weight::from_parts(16_553_000, 3530)
.saturating_add(RocksDbWeight::get().reads(2_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `ValidatorPool::CurrentEra` (r:1 w:1)
/// Proof: `ValidatorPool::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Babe::NextRandomness` (r:1 w:0)
/// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
/// Storage: `Babe::EpochStart` (r:1 w:0)
/// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PoolMembers` (r:101 w:0)
/// Proof: `ValidatorPool::PoolMembers` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::SelectionHistory` (r:100 w:21)
/// Proof: `ValidatorPool::SelectionHistory` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::PerformanceMetrics` (r:100 w:0)
/// Proof: `ValidatorPool::PerformanceMetrics` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::CurrentValidatorSet` (r:0 w:1)
/// Proof: `ValidatorPool::CurrentValidatorSet` (`max_values`: Some(1), `max_size`: Some(679), added: 1174, mode: `MaxEncodedLen`)
/// Storage: `ValidatorPool::EraStart` (r:0 w:1)
/// Proof: `ValidatorPool::EraStart` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// The range of component `p` is `[4, 100]`.
fn force_new_era(p: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `354 + p * (139 ±0)`
// Estimated: `3546 + p * (2556 ±0)`
// Minimum execution time: 68_990_000 picoseconds.
Weight::from_parts(55_692_892, 3546)
// Standard Error: 19_014
.saturating_add(Weight::from_parts(9_817_847, 0).saturating_mul(p.into()))
.saturating_add(RocksDbWeight::get().reads(4_u64))
.saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(p.into())))
.saturating_add(RocksDbWeight::get().writes(17_u64))
.saturating_add(Weight::from_parts(0, 2556).saturating_mul(p.into()))
}
/// Storage: `ValidatorPool::PoolMembers` (r:1 w:1)
/// Proof: `ValidatorPool::PoolMembers` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
fn update_category() -> Weight {
// Proof Size summary in bytes:
// Measured: `215`
// Estimated: `3546`
// Minimum execution time: 15_344_000 picoseconds.
Weight::from_parts(16_181_000, 3546)
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `ValidatorPool::EraLength` (r:0 w:1)
/// Proof: `ValidatorPool::EraLength` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn set_pool_parameters() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 6_159_000 picoseconds.
Weight::from_parts(6_422_000, 0)
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
}