more readable logs and use validators as offence reporters

Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
This commit is contained in:
Uncle Stinky 2025-12-09 16:24:41 +03:00
parent 3b80a7a94a
commit dc785e30d9
Signed by: st1nky
GPG Key ID: 016064BD97603B40
4 changed files with 86 additions and 15 deletions

2
Cargo.lock generated
View File

@ -3837,7 +3837,7 @@ dependencies = [
[[package]]
name = "ghost-slow-clap"
version = "0.4.7"
version = "0.4.8"
dependencies = [
"frame-benchmarking",
"frame-support",

View File

@ -1,6 +1,6 @@
[package]
name = "ghost-slow-clap"
version = "0.4.8"
version = "0.4.9"
description = "Applause protocol for the EVM bridge"
license.workspace = true
authors.workspace = true

View File

@ -455,13 +455,11 @@ pub mod pallet {
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn offchain_worker(now: BlockNumberFor<T>) {
if let Err(e) = Self::start_slow_clapping(now) {
log::info!(
target: LOG_TARGET,
"👻 Skipping slow clap at {:?}: {:?}",
now,
e,
)
match Self::start_slow_clapping(now) {
Ok(_) => {
log::info!(target: LOG_TARGET, "👻 Slow Clap #{:?} finished gracefully", now)
}
Err(e) => log::info!(target: LOG_TARGET, "👻 Slow Clap #{:?} failed: {:?}", now, e),
}
}
}
@ -812,9 +810,9 @@ impl<T: Config> Pallet<T> {
log::info!(
target: LOG_TARGET,
"👻 Offchain worker started for network #{:?} at block #{:?}",
network_in_use.0,
"👻 Slow Clap #{:?} started for network #{:?}",
block_number,
network_in_use.0,
);
let network_id_encoded = network_in_use.0.encode();
@ -826,11 +824,17 @@ impl<T: Config> Pallet<T> {
.try_lock()
.map_err(|_| OffchainErr::OffchainTimeoutPeriod(network_in_use.0))?;
Self::do_evm_claps_or_save_block(session_index, network_in_use.0, &network_in_use.1)
Self::do_evm_claps_or_save_block(
session_index,
block_number,
network_in_use.0,
&network_in_use.1,
)
}
fn do_evm_claps_or_save_block(
session_index: SessionIndex,
block_number: BlockNumberFor<T>,
network_id: NetworkIdOf<T>,
network_data: &NetworkData,
) -> OffchainResult<T, ()> {
@ -907,7 +911,8 @@ impl<T: Config> Pallet<T> {
log::info!(
target: LOG_TARGET,
"👻 Stored from_block is #{:?} for network {:?}",
"👻 Slow Clap #{:?} stored block #{:?} for network {:?}",
block_number,
new_block_range.0,
network_id,
);
@ -1220,8 +1225,9 @@ impl<T: Config> Pallet<T> {
})
.collect::<Vec<IdentificationTuple<T>>>();
let disabled_or_offence_bitmap = disabled_bitmap.bitor(offence_bitmap);
let not_enough_validators_left = validator_set_count
.saturating_sub(disabled_bitmap.bitor(offence_bitmap).count_ones())
.saturating_sub(disabled_or_offence_bitmap.count_ones())
.lt(&T::MinAuthoritiesNumber::get());
if not_enough_validators_left && offenders.len() > 0 {
@ -1256,7 +1262,17 @@ impl<T: Config> Pallet<T> {
offence_type,
};
if let Err(e) = T::ReportUnresponsiveness::report_offence(vec![], offence) {
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);
}
}

View File

@ -1295,6 +1295,61 @@ fn should_not_nullify_on_incorrect_block_commitment() {
});
}
#[test]
fn should_split_commit_slash_between_active_validators() {
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
new_test_ext().execute_with(|| {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
let mut block_commitment = CommitmentDetails {
last_stored_block: 9_500_000,
commits: 420,
last_updated: timestamp,
};
for extra_time in 1..=3 {
if extra_time < 3 {
let offences = Offences::get();
assert_eq!(offences.len(), 0);
}
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time;
for i in 0..3 {
assert_ok!(do_block_commitment(
session_index,
network_id,
i,
&block_commitment
));
}
}
System::assert_has_event(RuntimeEvent::SlowClap(
crate::Event::SomeAuthoritiesDelayed {
delayed: vec![(3, 3)],
},
));
let offences = Offences::get();
assert_eq!(offences.len(), 3);
for offence in offences {
assert_eq!(offence.0, vec![0, 1, 2]);
assert_eq!(offence.1.session_index, session_index);
assert_eq!(offence.1.validator_set_count, 4);
assert_eq!(offence.1.offenders, vec![(3, 3)]);
assert_eq!(offence.1.validator_set_count, 4);
assert_eq!(offence.1.offence_type, OffenceType::CommitmentOffence);
}
});
}
fn assert_clapped_amount(
session_index: &SessionIndex,
unique_hash: &H256,