fix calculation of median, include special case when there're no claps
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
This commit is contained in:
parent
f7b1b75d5a
commit
c4b16805f7
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ghost-slow-clap"
|
||||
version = "0.3.35"
|
||||
version = "0.3.36"
|
||||
description = "Applause protocol for the EVM bridge"
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
|
@ -90,7 +90,7 @@ pub struct Clap<AccountId, NetworkId, Balance> {
|
||||
pub amount: Balance,
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
|
||||
#[derive(Default, Clone, Copy, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
|
||||
pub struct SessionAuthorityInfo {
|
||||
pub claps: u32,
|
||||
pub disabled: bool,
|
||||
@ -967,10 +967,18 @@ impl<T: Config> Pallet<T> {
|
||||
.ok_or(OffchainErr::ErrorInEvmResponse)?)
|
||||
}
|
||||
|
||||
fn calculate_median_claps(session_index: &SessionIndex) -> u32 {
|
||||
let mut claps_in_session = ClapsInSession::<T>::get(session_index)
|
||||
.values()
|
||||
.filter_map(|value| (!value.disabled).then(|| value.claps))
|
||||
fn calculate_median_claps(
|
||||
actual_claps_in_session: &BTreeMap<AuthIndex, SessionAuthorityInfo>,
|
||||
authorities_len: usize,
|
||||
) -> u32 {
|
||||
let mut claps_in_session = (0..authorities_len)
|
||||
.filter_map(|index| {
|
||||
let clap_info = actual_claps_in_session
|
||||
.get(&(index as u32))
|
||||
.copied()
|
||||
.unwrap_or_default();
|
||||
(!clap_info.disabled).then(|| clap_info.claps)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if claps_in_session.is_empty() {
|
||||
@ -1083,9 +1091,10 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
|
||||
fn on_before_session_ending() {
|
||||
let session_index = T::ValidatorSet::session_index();
|
||||
let validators = T::ValidatorSet::validators();
|
||||
let authorities = Authorities::<T>::get(&session_index);
|
||||
let authorities_len = Authorities::<T>::get(&session_index).len();
|
||||
let actual_claps_in_session = ClapsInSession::<T>::get(&session_index);
|
||||
|
||||
let median_claps = Self::calculate_median_claps(&session_index);
|
||||
let median_claps = Self::calculate_median_claps(&actual_claps_in_session, authorities_len);
|
||||
|
||||
let offenders = validators
|
||||
.into_iter()
|
||||
@ -1105,7 +1114,7 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
|
||||
throttling: offenders.clone(),
|
||||
});
|
||||
|
||||
let validator_set_count = authorities.len() as u32;
|
||||
let validator_set_count = authorities_len as u32;
|
||||
let offence = ThrottlingOffence {
|
||||
session_index,
|
||||
validator_set_count,
|
||||
|
@ -119,6 +119,157 @@ fn test_throttling_slash_function() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_median_calculations_are_correct() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let data = BTreeMap::from([
|
||||
(
|
||||
0u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 0,
|
||||
disabled: true,
|
||||
},
|
||||
),
|
||||
(
|
||||
3u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 1,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
]);
|
||||
assert_eq!(SlowClap::calculate_median_claps(&data, 4), 0);
|
||||
|
||||
let data = BTreeMap::from([
|
||||
(
|
||||
0u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 0,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
1u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 69,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
2u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 69,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
3u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 420,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
]);
|
||||
assert_eq!(SlowClap::calculate_median_claps(&data, 4), 69);
|
||||
|
||||
let data = BTreeMap::from([
|
||||
(
|
||||
0u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 31,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
1u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 420,
|
||||
disabled: true,
|
||||
},
|
||||
),
|
||||
(
|
||||
2u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 69,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
3u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 156,
|
||||
disabled: true,
|
||||
},
|
||||
),
|
||||
]);
|
||||
assert_eq!(SlowClap::calculate_median_claps(&data, 4), 50);
|
||||
|
||||
let data = BTreeMap::from([
|
||||
(
|
||||
0u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 0,
|
||||
disabled: true,
|
||||
},
|
||||
),
|
||||
(
|
||||
1u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 420,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
2u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 0,
|
||||
disabled: true,
|
||||
},
|
||||
),
|
||||
(
|
||||
3u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 0,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
]);
|
||||
assert_eq!(SlowClap::calculate_median_claps(&data, 4), 210);
|
||||
|
||||
let data = BTreeMap::from([
|
||||
(
|
||||
0u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 0,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
1u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 420,
|
||||
disabled: true,
|
||||
},
|
||||
),
|
||||
(
|
||||
2u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 69,
|
||||
disabled: true,
|
||||
},
|
||||
),
|
||||
(
|
||||
3u32,
|
||||
SessionAuthorityInfo {
|
||||
claps: 0,
|
||||
disabled: false,
|
||||
},
|
||||
),
|
||||
]);
|
||||
assert_eq!(SlowClap::calculate_median_claps(&data, 4), 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn request_body_is_correct_for_get_block_number() {
|
||||
let (offchain, _) = TestOffchainExt::new();
|
||||
|
Loading…
Reference in New Issue
Block a user