From bd8d7145af320bac99485a8315e902dbc7f10657 Mon Sep 17 00:00:00 2001 From: Uncle Stretch Date: Thu, 26 Feb 2026 14:44:36 +0300 Subject: [PATCH] more optimized version for try_offend_validators Signed-off-by: Uncle Stretch --- pallets/slow-clap/Cargo.toml | 2 +- pallets/slow-clap/src/lib.rs | 62 +++++++++++++++++++---------------- pallets/slow-clap/src/mock.rs | 9 +++++ 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/pallets/slow-clap/Cargo.toml b/pallets/slow-clap/Cargo.toml index 034bbca..7e2a227 100644 --- a/pallets/slow-clap/Cargo.toml +++ b/pallets/slow-clap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ghost-slow-clap" -version = "0.4.24" +version = "0.4.25" description = "Applause protocol for the EVM bridge" license.workspace = true authors.workspace = true diff --git a/pallets/slow-clap/src/lib.rs b/pallets/slow-clap/src/lib.rs index 7e27021..e0012a0 100644 --- a/pallets/slow-clap/src/lib.rs +++ b/pallets/slow-clap/src/lib.rs @@ -1441,41 +1441,53 @@ impl Pallet { disabled_bitmap: BitMap, offence_type: OffenceType, ) -> Weight { - let validator_set_count = validators.len() as u32; + let mut weight = T::DbWeight::get().reads_writes(1, 1); + let validator_set_count = validators.len(); - let offenders = validators - .into_iter() - .enumerate() - .filter_map(|(index, id)| { - (offence_bitmap.exists(&(index as AuthIndex))).then(|| { - >::IdentificationOf::convert( - id.clone(), - ).map(|full_id| (id.clone(), full_id)) - }) - .flatten() - }) - .collect::>>(); + let mut offenders = Vec::with_capacity(offence_bitmap.count_ones() as usize); + let mut reporter_indexes = Vec::with_capacity(validator_set_count); - let disabled_or_offence_bitmap = disabled_bitmap.bitor(offence_bitmap); + let disabled_or_offence_bitmap = disabled_bitmap.bitor(offence_bitmap.clone()); + let validator_set_count = validator_set_count as u32; + + for (index, id) in validators.iter().enumerate() { + let authority_index = index as AuthIndex; + + if offence_bitmap.exists(&authority_index) { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + if let Some(full_id) = >::IdentificationOf::convert(id.clone()) + { + offenders.push((id.clone(), full_id)); + } + } else if !disabled_or_offence_bitmap.exists(&authority_index) { + reporter_indexes.push(index); + } + } + + let offenders_len = offenders.len() as u32; let not_enough_validators_left = validator_set_count .saturating_sub(disabled_or_offence_bitmap.count_ones()) .lt(&T::MinAuthoritiesNumber::get()); - if not_enough_validators_left && offenders.len() > 0 { + if not_enough_validators_left && offenders_len > 0 { Self::deposit_event(Event::::BlackSwan); - return T::DbWeight::get().writes(1); + return weight; } - let offenders_len = offenders.len() as u32; if offenders_len == 0 { let equilibrium_event = match offence_type { OffenceType::CommitmentOffence => Event::::AuthoritiesCommitmentEquilibrium, OffenceType::ThrottlingOffence(_) => Event::::AuthoritiesApplauseEquilibrium, }; Self::deposit_event(equilibrium_event); - return T::DbWeight::get().writes(1); + return weight; } + weight.saturating_accrue(T::DbWeight::get().reads(1)); + let reporters = T::ExposureListener::get_accounts_by_indexes(reporter_indexes.into_iter()); + let offence_event = match offence_type { OffenceType::CommitmentOffence => Event::::SomeAuthoritiesDelayed { delayed: offenders.clone(), @@ -1494,21 +1506,13 @@ impl Pallet { offence_type, }; - let reporters = validators - .into_iter() - .enumerate() - .filter_map(|(index, _)| { - (!disabled_or_offence_bitmap.exists(&(index as AuthIndex))) - .then(|| T::ExposureListener::get_account_by_index(index)) - .flatten() - }) - .collect(); - if let Err(e) = T::ReportUnresponsiveness::report_offence(reporters, offence) { sp_runtime::print(e); } - T::WeightInfo::try_offend_validators(offenders_len) + let extra_weight = T::WeightInfo::try_offend_validators(offenders_len); + + weight.saturating_add(extra_weight) } } diff --git a/pallets/slow-clap/src/mock.rs b/pallets/slow-clap/src/mock.rs index 17fe112..a64d3e6 100644 --- a/pallets/slow-clap/src/mock.rs +++ b/pallets/slow-clap/src/mock.rs @@ -177,6 +177,15 @@ impl ExposureListener for TestExposureListener where Balance: AtLeast32BitUnsigned + From, { + fn get_accounts_by_indexes( + indexes_iterator: impl Iterator, + ) -> sp_std::prelude::Vec { + let all_validators = FixedValidators::get(); + indexes_iterator + .filter_map(|i| all_validators.get(i).copied()) + .collect() + } + fn get_account_by_index(index: usize) -> Option { FixedValidators::get().get(index).copied() }