forked from ghostchain/ghost-node
		
	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]
 | 
					[package]
 | 
				
			||||||
name = "ghost-slow-clap"
 | 
					name = "ghost-slow-clap"
 | 
				
			||||||
version = "0.3.35"
 | 
					version = "0.3.36"
 | 
				
			||||||
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
 | 
				
			||||||
 | 
				
			|||||||
@ -90,7 +90,7 @@ pub struct Clap<AccountId, NetworkId, Balance> {
 | 
				
			|||||||
    pub amount: Balance,
 | 
					    pub amount: Balance,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Default, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
 | 
					#[derive(Default, Clone, Copy, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
 | 
				
			||||||
pub struct SessionAuthorityInfo {
 | 
					pub struct SessionAuthorityInfo {
 | 
				
			||||||
    pub claps: u32,
 | 
					    pub claps: u32,
 | 
				
			||||||
    pub disabled: bool,
 | 
					    pub disabled: bool,
 | 
				
			||||||
@ -967,10 +967,18 @@ impl<T: Config> Pallet<T> {
 | 
				
			|||||||
            .ok_or(OffchainErr::ErrorInEvmResponse)?)
 | 
					            .ok_or(OffchainErr::ErrorInEvmResponse)?)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn calculate_median_claps(session_index: &SessionIndex) -> u32 {
 | 
					    fn calculate_median_claps(
 | 
				
			||||||
        let mut claps_in_session = ClapsInSession::<T>::get(session_index)
 | 
					        actual_claps_in_session: &BTreeMap<AuthIndex, SessionAuthorityInfo>,
 | 
				
			||||||
            .values()
 | 
					        authorities_len: usize,
 | 
				
			||||||
            .filter_map(|value| (!value.disabled).then(|| value.claps))
 | 
					    ) -> 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<_>>();
 | 
					            .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if claps_in_session.is_empty() {
 | 
					        if claps_in_session.is_empty() {
 | 
				
			||||||
@ -1083,9 +1091,10 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
 | 
				
			|||||||
    fn on_before_session_ending() {
 | 
					    fn on_before_session_ending() {
 | 
				
			||||||
        let session_index = T::ValidatorSet::session_index();
 | 
					        let session_index = T::ValidatorSet::session_index();
 | 
				
			||||||
        let validators = T::ValidatorSet::validators();
 | 
					        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
 | 
					        let offenders = validators
 | 
				
			||||||
            .into_iter()
 | 
					            .into_iter()
 | 
				
			||||||
@ -1105,7 +1114,7 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
 | 
				
			|||||||
                throttling: offenders.clone(),
 | 
					                throttling: offenders.clone(),
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let validator_set_count = authorities.len() as u32;
 | 
					            let validator_set_count = authorities_len as u32;
 | 
				
			||||||
            let offence = ThrottlingOffence {
 | 
					            let offence = ThrottlingOffence {
 | 
				
			||||||
                session_index,
 | 
					                session_index,
 | 
				
			||||||
                validator_set_count,
 | 
					                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]
 | 
					#[test]
 | 
				
			||||||
fn request_body_is_correct_for_get_block_number() {
 | 
					fn request_body_is_correct_for_get_block_number() {
 | 
				
			||||||
    let (offchain, _) = TestOffchainExt::new();
 | 
					    let (offchain, _) = TestOffchainExt::new();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user