forked from ghostchain/ghost-node
		
	replacing the average claps in session with median to determine a harmful authority
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
This commit is contained in:
		
							parent
							
								
									04a63e234d
								
							
						
					
					
						commit
						9cb7f3c782
					
				@ -1,6 +1,6 @@
 | 
				
			|||||||
[package]
 | 
					[package]
 | 
				
			||||||
name = "ghost-slow-clap"
 | 
					name = "ghost-slow-clap"
 | 
				
			||||||
version = "0.3.17"
 | 
					version = "0.3.18"
 | 
				
			||||||
description = "Applause protocol for the EVM bridge"
 | 
					description = "Applause protocol for the EVM bridge"
 | 
				
			||||||
license.workspace = true
 | 
					license.workspace = true
 | 
				
			||||||
authors.workspace = true
 | 
					authors.workspace = true
 | 
				
			||||||
 | 
				
			|||||||
@ -858,9 +858,9 @@ impl<T: Config> Pallet<T> {
 | 
				
			|||||||
    fn is_good_actor(
 | 
					    fn is_good_actor(
 | 
				
			||||||
        authority_index: usize, 
 | 
					        authority_index: usize, 
 | 
				
			||||||
        session_index: SessionIndex,
 | 
					        session_index: SessionIndex,
 | 
				
			||||||
        average_claps: u32,
 | 
					        median_claps: u32,
 | 
				
			||||||
    ) -> bool {
 | 
					    ) -> bool {
 | 
				
			||||||
        if average_claps == 0 {
 | 
					        if median_claps == 0 {
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -869,10 +869,10 @@ impl<T: Config> Pallet<T> {
 | 
				
			|||||||
            .or_default()
 | 
					            .or_default()
 | 
				
			||||||
            .claps;
 | 
					            .claps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let authority_deviation = if number_of_claps < average_claps {
 | 
					        let authority_deviation = if number_of_claps < median_claps {
 | 
				
			||||||
            Perbill::from_rational(average_claps - number_of_claps, average_claps)
 | 
					            Perbill::from_rational(median_claps - number_of_claps, median_claps)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            Perbill::from_rational(number_of_claps - average_claps, average_claps)
 | 
					            Perbill::from_rational(number_of_claps - median_claps, median_claps)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        authority_deviation < Perbill::from_percent(T::OffenceThreshold::get())
 | 
					        authority_deviation < Perbill::from_percent(T::OffenceThreshold::get())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -886,6 +886,28 @@ impl<T: Config> Pallet<T> {
 | 
				
			|||||||
        }    
 | 
					        }    
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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))
 | 
				
			||||||
 | 
					            .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if claps_in_session.is_empty() {
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        claps_in_session.sort();
 | 
				
			||||||
 | 
					        let number_of_claps = claps_in_session.len();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if number_of_claps % 2 == 0 {
 | 
				
			||||||
 | 
					            let mid_left = claps_in_session[number_of_claps / 2 - 1];
 | 
				
			||||||
 | 
					            let mid_right = claps_in_session[number_of_claps / 2];
 | 
				
			||||||
 | 
					            (mid_left + mid_right) / 2
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            claps_in_session[number_of_claps / 2]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(test)]
 | 
					    #[cfg(test)]
 | 
				
			||||||
    fn set_test_authorities(authorities: Vec<T::AuthorityId>) {
 | 
					    fn set_test_authorities(authorities: Vec<T::AuthorityId>) {
 | 
				
			||||||
        let bounded_authorities = WeakBoundedVec::<_, T::MaxAuthorities>::try_from(authorities)
 | 
					        let bounded_authorities = WeakBoundedVec::<_, T::MaxAuthorities>::try_from(authorities)
 | 
				
			||||||
@ -931,21 +953,12 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
 | 
				
			|||||||
        let validators = T::ValidatorSet::validators();
 | 
					        let validators = T::ValidatorSet::validators();
 | 
				
			||||||
        let authorities = Authorities::<T>::get();
 | 
					        let authorities = Authorities::<T>::get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (sum_claps, total_claps) = ClapsInSession::<T>::get(&session_index)
 | 
					        let median_claps = Self::calculate_median_claps(&session_index);
 | 
				
			||||||
            .iter()
 | 
					 | 
				
			||||||
            .filter(|(_, value)| !value.disabled)
 | 
					 | 
				
			||||||
            .fold((0u32, 0u32), |(sum, total), (_, value)| 
 | 
					 | 
				
			||||||
                (sum.saturating_add(value.claps), total.saturating_add(1))
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let average_claps = sum_claps
 | 
					 | 
				
			||||||
            .checked_div(total_claps)
 | 
					 | 
				
			||||||
            .unwrap_or_default();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let offenders = validators
 | 
					        let offenders = validators
 | 
				
			||||||
            .into_iter()
 | 
					            .into_iter()
 | 
				
			||||||
            .enumerate()
 | 
					            .enumerate()
 | 
				
			||||||
            .filter(|(index, _)| !Self::is_good_actor(*index, session_index, average_claps))
 | 
					            .filter(|(index, _)| !Self::is_good_actor(*index, session_index, median_claps))
 | 
				
			||||||
            .filter_map(|(_, id)| {
 | 
					            .filter_map(|(_, id)| {
 | 
				
			||||||
                <T::ValidatorSet as ValidatorSetWithIdentification<T::AccountId>>::IdentificationOf::convert(
 | 
					                <T::ValidatorSet as ValidatorSetWithIdentification<T::AccountId>>::IdentificationOf::convert(
 | 
				
			||||||
                    id.clone(),
 | 
					                    id.clone(),
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user