diff --git a/pallets/slow-clap/Cargo.toml b/pallets/slow-clap/Cargo.toml index 49c68f1..a499bcb 100644 --- a/pallets/slow-clap/Cargo.toml +++ b/pallets/slow-clap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ghost-slow-clap" -version = "0.3.42" +version = "0.3.43" description = "Applause protocol for the EVM bridge" license.workspace = true authors.workspace = true diff --git a/pallets/slow-clap/src/lib.rs b/pallets/slow-clap/src/lib.rs index f5b9f16..3e932ca 100644 --- a/pallets/slow-clap/src/lib.rs +++ b/pallets/slow-clap/src/lib.rs @@ -72,7 +72,7 @@ const LOG_TARGET: &str = "runtime::ghost-slow-clap"; const DB_PREFIX: &[u8] = b"slow_clap::"; const FETCH_TIMEOUT_PERIOD: u64 = 3_000; -const LOCK_BLOCK_EXPIRATION: u64 = 10; +const LOCK_BLOCK_EXPIRATION: u64 = 20; pub type AuthIndex = u32; @@ -378,7 +378,8 @@ pub mod pallet { fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { if let Call::slow_clap { clap, signature } = call { - let authorities = Authorities::::get(&clap.session_index); + let (session_index, _) = Self::mended_session_index(&clap); + let authorities = Authorities::::get(&session_index); let authority = match authorities.get(clap.authority_index as usize) { Some(authority) => authority, None => return InvalidTransaction::BadSigner.into(), @@ -459,27 +460,49 @@ impl Pallet { hex_str } - fn try_slow_clap(clap: &Clap, BalanceOf>) -> DispatchResult { - let authorities = Authorities::::get(&clap.session_index); - ensure!( - authorities.get(clap.authority_index as usize).is_some(), - Error::::NotAnAuthority + fn mended_session_index( + clap: &Clap, BalanceOf>, + ) -> (SessionIndex, H256) { + let prev_session_index = clap.session_index.saturating_sub(1); + let clap_unique_hash = + Self::generate_unique_hash(&clap.receiver, &clap.amount, &clap.network_id); + + let received_claps_key = ( + prev_session_index, + &clap.transaction_hash, + &clap_unique_hash, ); + + let session_index = ReceivedClaps::::get(&received_claps_key) + .is_empty() + .then(|| clap.session_index) + .unwrap_or(prev_session_index); + + (session_index, clap_unique_hash) + } + + fn try_slow_clap(clap: &Clap, BalanceOf>) -> DispatchResult { + let (session_index, clap_unique_hash) = Self::mended_session_index(&clap); + let mut claps_in_session = ClapsInSession::::get(&session_index); + ensure!( - ClapsInSession::::get(&clap.session_index) + claps_in_session .get(&clap.authority_index) .map(|info| !info.disabled) .unwrap_or(true), Error::::CurrentValidatorIsDisabled ); - let clap_unique_hash = - Self::generate_unique_hash(&clap.receiver, &clap.amount, &clap.network_id); - let received_claps_key = ( - clap.session_index, - &clap.transaction_hash, - &clap_unique_hash, - ); + let disabled_authorites = claps_in_session + .values() + .filter(|info| info.disabled) + .count(); + + let active_authorities = Authorities::::get(&session_index) + .len() + .saturating_sub(disabled_authorites); + + let received_claps_key = (session_index, &clap.transaction_hash, &clap_unique_hash); let number_of_received_claps = ReceivedClaps::::try_mutate(&received_claps_key, |tree_of_claps| { @@ -498,15 +521,15 @@ impl Pallet { } })?; - ClapsInSession::::mutate(&clap.session_index, |claps_details| { - (*claps_details) - .entry(clap.authority_index) - .and_modify(|individual| (*individual).claps.saturating_inc()) - .or_insert(SessionAuthorityInfo { - claps: 1u32, - disabled: false, - }); - }); + claps_in_session + .entry(clap.authority_index) + .and_modify(|individual| individual.claps.saturating_inc()) + .or_insert(SessionAuthorityInfo { + claps: 1u32, + disabled: false, + }); + + ClapsInSession::::insert(&session_index, claps_in_session); Self::deposit_event(Event::::Clapped { authority_id: clap.authority_index, @@ -517,7 +540,7 @@ impl Pallet { }); let enough_authorities = - Perbill::from_rational(number_of_received_claps as u32, authorities.len() as u32) + Perbill::from_rational(number_of_received_claps as u32, active_authorities as u32) > Perbill::from_percent(T::ApplauseThreshold::get()); if enough_authorities { @@ -1113,8 +1136,8 @@ impl OneSessionHandler for Pallet { } fn on_before_session_ending() { - let session_index = T::ValidatorSet::session_index(); let validators = T::ValidatorSet::validators(); + let session_index = T::ValidatorSet::session_index().saturating_sub(1); let authorities_len = Authorities::::get(&session_index).len(); let claps_in_session = ClapsInSession::::get(&session_index);