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