applause based on the external expousre
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
This commit is contained in:
parent
0bb46482b2
commit
6a2b5a34d2
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-slow-clap"
|
name = "ghost-slow-clap"
|
||||||
version = "0.3.55"
|
version = "0.3.56"
|
||||||
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
|
||||||
|
|||||||
@ -8,8 +8,8 @@ use serde::{Deserialize, Deserializer};
|
|||||||
use frame_support::{
|
use frame_support::{
|
||||||
pallet_prelude::*,
|
pallet_prelude::*,
|
||||||
traits::{
|
traits::{
|
||||||
tokens::fungible::{Inspect, Mutate},
|
Currency, DisabledValidators, Get, OneSessionHandler, ValidatorSet,
|
||||||
DisabledValidators, Get, OneSessionHandler, ValidatorSet, ValidatorSetWithIdentification,
|
ValidatorSetWithIdentification,
|
||||||
},
|
},
|
||||||
WeakBoundedVec,
|
WeakBoundedVec,
|
||||||
};
|
};
|
||||||
@ -17,6 +17,7 @@ use frame_system::{
|
|||||||
offchain::{SendTransactionTypes, SubmitTransaction},
|
offchain::{SendTransactionTypes, SubmitTransaction},
|
||||||
pallet_prelude::*,
|
pallet_prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use pallet::*;
|
pub use pallet::*;
|
||||||
|
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
@ -27,12 +28,12 @@ use sp_runtime::{
|
|||||||
storage_lock::{StorageLock, Time},
|
storage_lock::{StorageLock, Time},
|
||||||
HttpError,
|
HttpError,
|
||||||
},
|
},
|
||||||
traits::{BlockNumberProvider, Convert, Saturating, TrailingZeroInput},
|
traits::{AtLeast32BitUnsigned, BlockNumberProvider, Convert, Saturating, TrailingZeroInput},
|
||||||
Perbill, RuntimeAppPublic, RuntimeDebug,
|
Perbill, RuntimeAppPublic, RuntimeDebug,
|
||||||
};
|
};
|
||||||
use sp_staking::{
|
use sp_staking::{
|
||||||
offence::{Kind, Offence, ReportOffence},
|
offence::{Kind, Offence, ReportOffence},
|
||||||
SessionIndex,
|
EraIndex, SessionIndex,
|
||||||
};
|
};
|
||||||
use sp_std::{collections::btree_map::BTreeMap, prelude::*, vec::Vec};
|
use sp_std::{collections::btree_map::BTreeMap, prelude::*, vec::Vec};
|
||||||
|
|
||||||
@ -202,7 +203,7 @@ impl<NetworkId: core::fmt::Debug> core::fmt::Debug for OffchainErr<NetworkId> {
|
|||||||
pub type NetworkIdOf<T> = <<T as Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId;
|
pub type NetworkIdOf<T> = <<T as Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId;
|
||||||
|
|
||||||
pub type BalanceOf<T> =
|
pub type BalanceOf<T> =
|
||||||
<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
|
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||||
|
|
||||||
pub type ValidatorId<T> = <<T as Config>::ValidatorSet as ValidatorSet<
|
pub type ValidatorId<T> = <<T as Config>::ValidatorSet as ValidatorSet<
|
||||||
<T as frame_system::Config>::AccountId,
|
<T as frame_system::Config>::AccountId,
|
||||||
@ -217,6 +218,12 @@ pub type IdentificationTuple<T> = (
|
|||||||
|
|
||||||
type OffchainResult<T, A> = Result<A, OffchainErr<NetworkIdOf<T>>>;
|
type OffchainResult<T, A> = Result<A, OffchainErr<NetworkIdOf<T>>>;
|
||||||
|
|
||||||
|
pub trait ApplauseListener<Balance: AtLeast32BitUnsigned> {
|
||||||
|
fn get_current_era() -> EraIndex;
|
||||||
|
fn get_threshold_amount(era: EraIndex) -> Balance;
|
||||||
|
fn get_validator_total_exposure(era: EraIndex, index: usize) -> Balance;
|
||||||
|
}
|
||||||
|
|
||||||
#[frame_support::pallet]
|
#[frame_support::pallet]
|
||||||
pub mod pallet {
|
pub mod pallet {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -239,7 +246,7 @@ pub mod pallet {
|
|||||||
+ MaxEncodedLen;
|
+ MaxEncodedLen;
|
||||||
|
|
||||||
type ValidatorSet: ValidatorSetWithIdentification<Self::AccountId>;
|
type ValidatorSet: ValidatorSetWithIdentification<Self::AccountId>;
|
||||||
type Currency: Inspect<Self::AccountId> + Mutate<Self::AccountId>;
|
type Currency: Currency<Self::AccountId>;
|
||||||
type NetworkDataHandler: NetworkDataBasicHandler
|
type NetworkDataHandler: NetworkDataBasicHandler
|
||||||
+ NetworkDataInspectHandler<NetworkData>
|
+ NetworkDataInspectHandler<NetworkData>
|
||||||
+ NetworkDataMutateHandler<NetworkData, BalanceOf<Self>>;
|
+ NetworkDataMutateHandler<NetworkData, BalanceOf<Self>>;
|
||||||
@ -250,6 +257,7 @@ pub mod pallet {
|
|||||||
ThrottlingOffence<IdentificationTuple<Self>>,
|
ThrottlingOffence<IdentificationTuple<Self>>,
|
||||||
>;
|
>;
|
||||||
type DisabledValidators: DisabledValidators;
|
type DisabledValidators: DisabledValidators;
|
||||||
|
type ApplauseListener: ApplauseListener<BalanceOf<Self>>;
|
||||||
|
|
||||||
#[pallet::constant]
|
#[pallet::constant]
|
||||||
type MaxAuthorities: Get<u32>;
|
type MaxAuthorities: Get<u32>;
|
||||||
@ -311,6 +319,19 @@ pub mod pallet {
|
|||||||
TimeWentBackwards,
|
TimeWentBackwards,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pallet::storage]
|
||||||
|
#[pallet::getter(fn clapped_amount)]
|
||||||
|
pub(super) type ClappedAmount<T: Config> = StorageNMap<
|
||||||
|
_,
|
||||||
|
(
|
||||||
|
NMapKey<Twox64Concat, SessionIndex>,
|
||||||
|
NMapKey<Twox64Concat, H256>,
|
||||||
|
NMapKey<Twox64Concat, H256>,
|
||||||
|
),
|
||||||
|
BalanceOf<T>,
|
||||||
|
ValueQuery,
|
||||||
|
>;
|
||||||
|
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
#[pallet::getter(fn block_commitments)]
|
#[pallet::getter(fn block_commitments)]
|
||||||
pub(super) type BlockCommitments<T: Config> = StorageMap<
|
pub(super) type BlockCommitments<T: Config> = StorageMap<
|
||||||
@ -584,33 +605,23 @@ impl<T: Config> Pallet<T> {
|
|||||||
let (session_index, clap_unique_hash) = Self::mended_session_index(&clap);
|
let (session_index, clap_unique_hash) = Self::mended_session_index(&clap);
|
||||||
let mut claps_in_session = ClapsInSession::<T>::get(&session_index);
|
let mut claps_in_session = ClapsInSession::<T>::get(&session_index);
|
||||||
|
|
||||||
let disabled_authorities = claps_in_session
|
|
||||||
.values()
|
|
||||||
.filter(|info| info.disabled)
|
|
||||||
.count();
|
|
||||||
|
|
||||||
let active_authorities = Authorities::<T>::get(&session_index)
|
|
||||||
.len()
|
|
||||||
.saturating_sub(disabled_authorities);
|
|
||||||
|
|
||||||
let received_claps_key = (session_index, &clap.transaction_hash, &clap_unique_hash);
|
let received_claps_key = (session_index, &clap.transaction_hash, &clap_unique_hash);
|
||||||
|
|
||||||
let number_of_received_claps =
|
ReceivedClaps::<T>::try_mutate(&received_claps_key, |tree_of_claps| {
|
||||||
ReceivedClaps::<T>::try_mutate(&received_claps_key, |tree_of_claps| {
|
let number_of_claps = tree_of_claps.len();
|
||||||
let number_of_claps = tree_of_claps.len();
|
match (tree_of_claps.contains(&clap.authority_index), clap.removed) {
|
||||||
match (tree_of_claps.contains(&clap.authority_index), clap.removed) {
|
(true, true) => tree_of_claps
|
||||||
(true, true) => tree_of_claps
|
.remove(&clap.authority_index)
|
||||||
.remove(&clap.authority_index)
|
.then(|| number_of_claps.saturating_sub(1))
|
||||||
.then(|| number_of_claps.saturating_sub(1))
|
.ok_or(Error::<T>::UnregisteredClapRemove),
|
||||||
.ok_or(Error::<T>::UnregisteredClapRemove),
|
(true, false) => Err(Error::<T>::AlreadyClapped),
|
||||||
(true, false) => Err(Error::<T>::AlreadyClapped),
|
(false, true) => Err(Error::<T>::UnregisteredClapRemove),
|
||||||
(false, true) => Err(Error::<T>::UnregisteredClapRemove),
|
(false, false) => tree_of_claps
|
||||||
(false, false) => tree_of_claps
|
.try_insert(clap.authority_index)
|
||||||
.try_insert(clap.authority_index)
|
.map(|_| number_of_claps.saturating_add(1))
|
||||||
.map(|_| number_of_claps.saturating_add(1))
|
.map_err(|_| Error::<T>::TooMuchAuthorities),
|
||||||
.map_err(|_| Error::<T>::TooMuchAuthorities),
|
}
|
||||||
}
|
})?;
|
||||||
})?;
|
|
||||||
|
|
||||||
claps_in_session
|
claps_in_session
|
||||||
.entry(clap.authority_index)
|
.entry(clap.authority_index)
|
||||||
@ -631,8 +642,7 @@ impl<T: Config> Pallet<T> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let enough_authorities =
|
let enough_authorities =
|
||||||
Perbill::from_rational(number_of_received_claps as u32, active_authorities as u32)
|
Self::validator_clap_by_amount(clap.authority_index, &received_claps_key);
|
||||||
> Perbill::from_percent(T::ApplauseThreshold::get());
|
|
||||||
|
|
||||||
if enough_authorities {
|
if enough_authorities {
|
||||||
let _ = Self::try_applause(&clap, &received_claps_key).inspect_err(|error_msg| {
|
let _ = Self::try_applause(&clap, &received_claps_key).inspect_err(|error_msg| {
|
||||||
@ -647,6 +657,24 @@ impl<T: Config> Pallet<T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validator_clap_by_amount(
|
||||||
|
authority_index: AuthIndex,
|
||||||
|
received_claps_key: &(SessionIndex, &H256, &H256),
|
||||||
|
) -> bool {
|
||||||
|
let era = T::ApplauseListener::get_current_era();
|
||||||
|
let threshold_amount = T::ApplauseListener::get_threshold_amount(era);
|
||||||
|
let new_clapped_amount =
|
||||||
|
T::ApplauseListener::get_validator_total_exposure(era, authority_index as usize);
|
||||||
|
|
||||||
|
let total_clapped = ClappedAmount::<T>::mutate(received_claps_key, |clapped_amount| {
|
||||||
|
let total_clapped = clapped_amount.saturating_add(new_clapped_amount);
|
||||||
|
*clapped_amount = total_clapped;
|
||||||
|
total_clapped
|
||||||
|
});
|
||||||
|
|
||||||
|
total_clapped >= threshold_amount
|
||||||
|
}
|
||||||
|
|
||||||
fn try_applause(
|
fn try_applause(
|
||||||
clap: &Clap<T::AccountId, NetworkIdOf<T>, BalanceOf<T>>,
|
clap: &Clap<T::AccountId, NetworkIdOf<T>, BalanceOf<T>>,
|
||||||
received_claps_key: &(SessionIndex, &H256, &H256),
|
received_claps_key: &(SessionIndex, &H256, &H256),
|
||||||
@ -670,9 +698,7 @@ impl<T: Config> Pallet<T> {
|
|||||||
let _ = T::NetworkDataHandler::accumulate_commission(&commission)
|
let _ = T::NetworkDataHandler::accumulate_commission(&commission)
|
||||||
.map_err(|_| Error::<T>::CouldNotAccumulateCommission)?;
|
.map_err(|_| Error::<T>::CouldNotAccumulateCommission)?;
|
||||||
|
|
||||||
if final_amount > T::Currency::minimum_balance() {
|
let _ = T::Currency::deposit_creating(&clap.receiver, final_amount);
|
||||||
T::Currency::mint_into(&clap.receiver, final_amount)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
*is_applaused = true;
|
*is_applaused = true;
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use pallet_session::historical as pallet_session_historical;
|
|||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
curve::PiecewiseLinear,
|
curve::PiecewiseLinear,
|
||||||
testing::{TestXt, UintAuthorityId},
|
testing::{TestXt, UintAuthorityId},
|
||||||
traits::ConvertInto,
|
traits::{AtLeast32BitUnsigned, ConvertInto},
|
||||||
Permill,
|
Permill,
|
||||||
};
|
};
|
||||||
use sp_staking::{
|
use sp_staking::{
|
||||||
@ -20,7 +20,7 @@ use sp_staking::{
|
|||||||
use sp_runtime::BuildStorage;
|
use sp_runtime::BuildStorage;
|
||||||
|
|
||||||
use crate as slow_clap;
|
use crate as slow_clap;
|
||||||
use crate::Config;
|
use crate::{ApplauseListener, Config, EraIndex};
|
||||||
|
|
||||||
type Block = frame_system::mocking::MockBlock<Runtime>;
|
type Block = frame_system::mocking::MockBlock<Runtime>;
|
||||||
|
|
||||||
@ -174,6 +174,32 @@ impl pallet_balances::Config for Runtime {
|
|||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Balance = u64;
|
||||||
|
|
||||||
|
pub struct TestSomeCoolTrait;
|
||||||
|
impl ApplauseListener<Balance> for TestSomeCoolTrait
|
||||||
|
where
|
||||||
|
Balance: AtLeast32BitUnsigned + From<u64>,
|
||||||
|
{
|
||||||
|
fn get_current_era() -> EraIndex {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_threshold_amount(_era: EraIndex) -> Balance {
|
||||||
|
666_666_667u64.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_validator_total_exposure(_era: EraIndex, index: usize) -> Balance {
|
||||||
|
match index {
|
||||||
|
0 => 500_000_000u64,
|
||||||
|
1 => 300_000_000u64,
|
||||||
|
2 => 200_000_000u64,
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Config for Runtime {
|
impl Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type AuthorityId = UintAuthorityId;
|
type AuthorityId = UintAuthorityId;
|
||||||
@ -184,6 +210,7 @@ impl Config for Runtime {
|
|||||||
type BlockNumberProvider = System;
|
type BlockNumberProvider = System;
|
||||||
type ReportUnresponsiveness = OffenceHandler;
|
type ReportUnresponsiveness = OffenceHandler;
|
||||||
type DisabledValidators = Session;
|
type DisabledValidators = Session;
|
||||||
|
type ApplauseListener = TestSomeCoolTrait;
|
||||||
|
|
||||||
type MaxAuthorities = ConstU32<5>;
|
type MaxAuthorities = ConstU32<5>;
|
||||||
type ApplauseThreshold = ConstU32<50>;
|
type ApplauseThreshold = ConstU32<50>;
|
||||||
|
|||||||
@ -562,25 +562,25 @@ fn should_applause_and_take_next_claps() {
|
|||||||
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
assert_eq!(Balances::balance(&receiver), 0);
|
assert_eq!(Balances::total_balance(&receiver), 0);
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 0, false));
|
assert_ok!(do_clap_from(session_index, network_id, 0, false));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
assert_eq!(Balances::balance(&receiver), 0);
|
assert_eq!(Balances::total_balance(&receiver), 0);
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
assert_eq!(Balances::balance(&receiver), amount);
|
assert_eq!(Balances::total_balance(&receiver), amount);
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
assert_eq!(Balances::balance(&receiver), amount);
|
assert_eq!(Balances::total_balance(&receiver), amount);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,8 +812,8 @@ fn should_clap_without_applause_on_gatekeeper_amount_overflow() {
|
|||||||
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key_first),
|
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key_first),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
assert_eq!(Balances::balance(&first_receiver), big_amount);
|
assert_eq!(Balances::total_balance(&first_receiver), big_amount);
|
||||||
assert_eq!(Balances::balance(&second_receiver), 0);
|
assert_eq!(Balances::total_balance(&second_receiver), 0);
|
||||||
|
|
||||||
for authority_index in 0..=2 {
|
for authority_index in 0..=2 {
|
||||||
let clap = Clap {
|
let clap = Clap {
|
||||||
@ -831,8 +831,8 @@ fn should_clap_without_applause_on_gatekeeper_amount_overflow() {
|
|||||||
assert_ok!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature));
|
assert_ok!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(Balances::balance(&first_receiver), big_amount);
|
assert_eq!(Balances::total_balance(&first_receiver), big_amount);
|
||||||
assert_eq!(Balances::balance(&second_receiver), 0);
|
assert_eq!(Balances::total_balance(&second_receiver), 0);
|
||||||
|
|
||||||
assert_eq!(Networks::gatekeeper_amount(network_id), big_amount);
|
assert_eq!(Networks::gatekeeper_amount(network_id), big_amount);
|
||||||
assert_eq!(Networks::bridged_imbalance().bridged_in, big_amount);
|
assert_eq!(Networks::bridged_imbalance().bridged_in, big_amount);
|
||||||
@ -876,8 +876,8 @@ fn should_clap_without_applause_on_commission_overflow() {
|
|||||||
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key_first),
|
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key_first),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
assert_eq!(Balances::balance(&first_receiver), big_amount);
|
assert_eq!(Balances::total_balance(&first_receiver), big_amount);
|
||||||
assert_eq!(Balances::balance(&second_receiver), 0);
|
assert_eq!(Balances::total_balance(&second_receiver), 0);
|
||||||
|
|
||||||
for authority_index in 0..=2 {
|
for authority_index in 0..=2 {
|
||||||
let clap = Clap {
|
let clap = Clap {
|
||||||
@ -895,8 +895,8 @@ fn should_clap_without_applause_on_commission_overflow() {
|
|||||||
assert_ok!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature));
|
assert_ok!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(Balances::balance(&first_receiver), big_amount);
|
assert_eq!(Balances::total_balance(&first_receiver), big_amount);
|
||||||
assert_eq!(Balances::balance(&second_receiver), 0);
|
assert_eq!(Balances::total_balance(&second_receiver), 0);
|
||||||
|
|
||||||
assert_eq!(Networks::gatekeeper_amount(network_id), big_amount);
|
assert_eq!(Networks::gatekeeper_amount(network_id), big_amount);
|
||||||
assert_eq!(Networks::gatekeeper_amount(network_id_other), big_amount);
|
assert_eq!(Networks::gatekeeper_amount(network_id_other), big_amount);
|
||||||
@ -967,13 +967,13 @@ fn should_avoid_applause_during_nullification_period() {
|
|||||||
|
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 0, false));
|
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, 1, false));
|
||||||
assert_eq!(Balances::balance(&receiver), 0);
|
assert_eq!(Balances::total_balance(&receiver), 0);
|
||||||
|
|
||||||
Networks::on_finalize(System::block_number());
|
Networks::on_finalize(System::block_number());
|
||||||
assert_eq!(Networks::is_nullification_period(), false);
|
assert_eq!(Networks::is_nullification_period(), false);
|
||||||
|
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
||||||
assert_eq!(Balances::balance(&receiver), amount);
|
assert_eq!(Balances::total_balance(&receiver), amount);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -995,7 +995,7 @@ fn should_avoid_session_overlap_on_mended_session_index() {
|
|||||||
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
assert_eq!(Balances::balance(&receiver), 0u64);
|
assert_eq!(Balances::total_balance(&receiver), 0u64);
|
||||||
|
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
||||||
@ -1004,7 +1004,7 @@ fn should_avoid_session_overlap_on_mended_session_index() {
|
|||||||
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
assert_eq!(Balances::balance(&receiver), amount);
|
assert_eq!(Balances::total_balance(&receiver), amount);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1094,7 +1094,7 @@ fn should_not_fail_on_sub_existential_balance() {
|
|||||||
assert_eq!(Networks::gatekeeper_amount(network_id), 0);
|
assert_eq!(Networks::gatekeeper_amount(network_id), 0);
|
||||||
assert_eq!(Networks::bridged_imbalance().bridged_in, 0);
|
assert_eq!(Networks::bridged_imbalance().bridged_in, 0);
|
||||||
assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
|
assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
|
||||||
assert_eq!(Balances::balance(&receiver), 0);
|
assert_eq!(Balances::total_balance(&receiver), 0);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
SlowClap::applauses_for_transaction(&received_claps_key),
|
SlowClap::applauses_for_transaction(&received_claps_key),
|
||||||
false
|
false
|
||||||
@ -1108,7 +1108,7 @@ fn should_not_fail_on_sub_existential_balance() {
|
|||||||
assert_eq!(Networks::gatekeeper_amount(network_id), amount);
|
assert_eq!(Networks::gatekeeper_amount(network_id), amount);
|
||||||
assert_eq!(Networks::bridged_imbalance().bridged_in, 0);
|
assert_eq!(Networks::bridged_imbalance().bridged_in, 0);
|
||||||
assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
|
assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
|
||||||
assert_eq!(Balances::balance(&receiver), 0);
|
assert_eq!(Balances::total_balance(&receiver), 0);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
SlowClap::applauses_for_transaction(&received_claps_key),
|
SlowClap::applauses_for_transaction(&received_claps_key),
|
||||||
true
|
true
|
||||||
@ -1175,6 +1175,40 @@ fn should_register_block_commitments() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_accumulate_clapped_amount() {
|
||||||
|
let (network_id, transaction_hash, unique_transaction_hash) =
|
||||||
|
generate_unique_hash(None, None, None, None);
|
||||||
|
|
||||||
|
new_test_ext().execute_with(|| {
|
||||||
|
let session_index = advance_session_and_get_index();
|
||||||
|
let storage_key = (session_index, transaction_hash, unique_transaction_hash);
|
||||||
|
|
||||||
|
let era = <Runtime as Config>::ApplauseListener::get_current_era();
|
||||||
|
let threshold_amount = <Runtime as Config>::ApplauseListener::get_threshold_amount(era);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
ClappedAmount::<Runtime>::get(&storage_key) < threshold_amount,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
||||||
|
assert_eq!(
|
||||||
|
ClappedAmount::<Runtime>::get(&storage_key) < threshold_amount,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
||||||
|
assert_eq!(
|
||||||
|
ClappedAmount::<Runtime>::get(&storage_key) < threshold_amount,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
assert_ok!(do_clap_from(session_index, network_id, 0, false));
|
||||||
|
assert_eq!(
|
||||||
|
ClappedAmount::<Runtime>::get(&storage_key) > threshold_amount,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn advance_session_and_get_index() -> u32 {
|
fn advance_session_and_get_index() -> u32 {
|
||||||
advance_session();
|
advance_session();
|
||||||
assert_eq!(Session::validators(), Vec::<u64>::new());
|
assert_eq!(Session::validators(), Vec::<u64>::new());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user