From 46aa18aafe90c1436f8eecb22561706ed9cb9a8c Mon Sep 17 00:00:00 2001 From: Uncle Stinky Date: Wed, 27 Aug 2025 14:41:46 +0300 Subject: [PATCH] implement cross session claim via self_applause Signed-off-by: Uncle Stinky --- pallets/slow-clap/Cargo.toml | 2 +- pallets/slow-clap/src/lib.rs | 56 +++++++++++++++++++++++++--------- pallets/slow-clap/src/tests.rs | 44 ++++++++++++++++++++------ 3 files changed, 77 insertions(+), 25 deletions(-) diff --git a/pallets/slow-clap/Cargo.toml b/pallets/slow-clap/Cargo.toml index d0d47b4..071a066 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.40" +version = "0.3.41" 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 1e2eefd..e49bb1f 100644 --- a/pallets/slow-clap/src/lib.rs +++ b/pallets/slow-clap/src/lib.rs @@ -574,32 +574,55 @@ impl Pallet { fn applause_if_posible( network_id: NetworkIdOf, - session_index: SessionIndex, + prev_session_index: SessionIndex, transaction_hash: H256, receiver: T::AccountId, amount: BalanceOf, ) -> DispatchResult { + let curr_session_index = prev_session_index.saturating_add(1); let clap_unique_hash = Self::generate_unique_hash(&receiver, &amount, &network_id); - let received_claps_key = (session_index, &transaction_hash, &clap_unique_hash); + let prev_received_claps_key = (prev_session_index, &transaction_hash, &clap_unique_hash); + let curr_received_claps_key = (curr_session_index, &transaction_hash, &clap_unique_hash); + + let prev_authorities = Authorities::::get(&prev_session_index); + let curr_authorities = Authorities::::get(&curr_session_index); + + let prev_received_claps = ReceivedClaps::::get(&prev_received_claps_key).into_inner(); + let curr_received_claps = ReceivedClaps::::get(&curr_received_claps_key).into_inner(); + + let summary_authority_claps_length = curr_received_claps + .difference(&prev_received_claps) + .filter_map(|&index| { + curr_authorities + .get(index as usize) + .map(|curr_authority| { + prev_authorities + .iter() + .position(|prev_authority| curr_authority == prev_authority) + }) + .flatten() + }) + .count() + .saturating_add(curr_received_claps.len()); let clap = Clap { authority_index: Default::default(), block_number: Default::default(), - removed: false, - session_index, + removed: Default::default(), + session_index: Default::default(), + transaction_hash: Default::default(), network_id, receiver, amount, - transaction_hash, }; let enough_authorities = Perbill::from_rational( - ReceivedClaps::::get(&received_claps_key).len() as u32, - Authorities::::get(session_index).len() as u32, + summary_authority_claps_length as u32, + Authorities::::get(prev_session_index).len() as u32, ) > Perbill::from_percent(T::ApplauseThreshold::get()); ensure!(enough_authorities, Error::::NotEnoughClaps); - Self::try_applause(&clap, &received_claps_key)?; + Self::try_applause(&clap, &prev_received_claps_key)?; Ok(()) } @@ -766,14 +789,17 @@ impl Pallet { Some(_) if from_block.le(&to_block) => { let adjusted_to_block = estimated_block .checked_sub(from_block) - .map(|current_distance| current_distance - .le(&max_block_distance) - .then(|| estimated_block) - ) + .map(|current_distance| { + current_distance + .le(&max_block_distance) + .then(|| estimated_block) + }) .flatten() - .unwrap_or(from_block - .saturating_add(max_block_distance) - .min(estimated_block)); + .unwrap_or( + from_block + .saturating_add(max_block_distance) + .min(estimated_block), + ); (from_block, adjusted_to_block) } _ => (to_block, to_block), diff --git a/pallets/slow-clap/src/tests.rs b/pallets/slow-clap/src/tests.rs index 27370b8..13907bd 100644 --- a/pallets/slow-clap/src/tests.rs +++ b/pallets/slow-clap/src/tests.rs @@ -991,7 +991,6 @@ fn should_self_applause_if_enough_received_claps() { assert_ok!(do_clap_from(session_index, network_id, 0, false)); assert_ok!(do_clap_from(session_index, network_id, 1, false)); - assert_ok!(do_clap_from(session_index, network_id, 2, false)); assert_eq!( pallet::ApplausesForTransaction::::get(&storage_key), @@ -999,14 +998,17 @@ fn should_self_applause_if_enough_received_claps() { ); assert_eq!(Balances::balance(&receiver), 0); - assert_ok!(SlowClap::self_applause( - RuntimeOrigin::signed(receiver), - network_id, - session_index, - transaction_hash, - receiver, - amount, - )); + assert_err!( + SlowClap::self_applause( + RuntimeOrigin::signed(receiver), + network_id, + session_index, + transaction_hash, + receiver, + amount, + ), + Error::::NotEnoughClaps + ); assert_eq!( pallet::ApplausesForTransaction::::get(&storage_key), false @@ -1015,6 +1017,26 @@ fn should_self_applause_if_enough_received_claps() { Networks::on_finalize(System::block_number()); + advance_session(); + let next_session_index = Session::session_index(); + let next_storage_key = ( + next_session_index, + transaction_hash, + unique_transaction_hash, + ); + assert_ok!(do_clap_from(next_session_index, network_id, 2, false)); + + assert_err!( + SlowClap::self_applause( + RuntimeOrigin::signed(receiver), + network_id, + next_session_index, + transaction_hash, + receiver, + amount, + ), + Error::::NotEnoughClaps + ); assert_ok!(SlowClap::self_applause( RuntimeOrigin::signed(receiver), network_id, @@ -1027,6 +1049,10 @@ fn should_self_applause_if_enough_received_claps() { pallet::ApplausesForTransaction::::get(&storage_key), true ); + assert_eq!( + pallet::ApplausesForTransaction::::get(&next_storage_key), + false + ); assert_eq!(Balances::balance(&receiver), amount); }); }