From a04215bc1373114e6e519f5ef594516e5864d383 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 20 Sep 2025 02:01:03 -0400 Subject: [PATCH] Remove commented-out slashing code from `serai-validator-sets-pallet` Deferred to https://github.com/serai-dex/serai/issues/657. --- substrate/validator-sets/src/lib.rs | 238 +--------------------------- 1 file changed, 4 insertions(+), 234 deletions(-) diff --git a/substrate/validator-sets/src/lib.rs b/substrate/validator-sets/src/lib.rs index 21a281c5..2e144109 100644 --- a/substrate/validator-sets/src/lib.rs +++ b/substrate/validator-sets/src/lib.rs @@ -14,31 +14,6 @@ use allocations::*; mod sessions; use sessions::{*, GenesisValidators as GenesisValidatorsContainer}; -/* -#[derive(Debug, Encode, Decode, PartialEq, Eq, Clone)] -pub struct MembershipProof(pub Public, pub PhantomData); -impl GetSessionNumber for MembershipProof { - fn session(&self) -> u32 { - let current = Pallet::::session(NetworkId::Serai).unwrap().0; - if Babe::::is_member(&BabeAuthorityId::from(self.0)) { - current - } else { - // if it isn't in the current session, it should have been in the previous one. - current - 1 - } - } -} -impl GetValidatorCount for MembershipProof { - // We only implement and this interface to satisfy trait requirements - // Although this might return the wrong count if the offender was in the previous set, we don't - // rely on it and Substrate only relies on it to offer economic calculations we also don't rely - // on - fn validator_count(&self) -> u32 { - u32::try_from(Babe::::authorities().len()).unwrap() - } -} -*/ - #[expect(clippy::cast_possible_truncation)] #[frame_support::pallet] mod pallet { @@ -157,7 +132,7 @@ mod pallet { type DelayedDeallocations = DelayedDeallocations; } - /* + /* TODO /// The generated key pair for a given validator set instance. #[pallet::storage] #[pallet::getter(fn keys)] @@ -169,10 +144,6 @@ mod pallet { pub type PendingSlashReport = StorageMap<_, Identity, ExternalNetworkId, Public, OptionQuery>; - /// Disabled validators. - #[pallet::storage] - pub type SeraiDisabledIndices = StorageMap<_, Identity, u32, Public, OptionQuery>; - #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { @@ -318,21 +289,7 @@ mod pallet { } } - /* - fn session_to_unlock_on_for_current_set(network: NetworkId) -> Option { - let mut to_unlock_on = Self::session(network)?; - // Move to the next session, as deallocating currently in-use stake is obviously invalid - to_unlock_on.0 += 1; - if network == NetworkId::Serai { - // Since the next Serai set will already have been decided, we can only deallocate one - // session later - to_unlock_on.0 += 1; - } - // Increase the session by one, creating a cooldown period - to_unlock_on.0 += 1; - Some(to_unlock_on) - } - + /* TODO /// Decreases a validator's allocation to a set. /// /// Errors if the capacity provided by this allocation is in use. @@ -349,7 +306,6 @@ mod pallet { account: T::AccountId, amount: Amount, ) -> Result { - /* TODO // Check it's safe to decrease this set's stake by this amount if let NetworkId::External(n) = network { let new_total_staked = Self::total_allocated_stake(NetworkId::from(n)) @@ -378,7 +334,6 @@ mod pallet { Err(Error::::DeallocationWouldRemoveFaultTolerance)?; } } - */ Sessions::::decrease_allocation(network, account, amount) } @@ -411,20 +366,6 @@ mod pallet { }); } - pub(crate) fn rotate_session() { - Self::retire_set(ValidatorSet { network: NetworkId::Serai, session: prior_serai_session }); - - // Clear SeraiDisabledIndices, only preserving keys still present in the new session - // First drain so we don't mutate as we iterate - let mut disabled = vec![]; - for (_, validator) in SeraiDisabledIndices::::drain() { - disabled.push(validator); - } - for disabled in disabled { - Self::disable_serai_validator(disabled); - } - } - /// Returns the required stake in terms SRI for a given `Balance`. pub fn required_stake(balance: &ExternalBalance) -> SubstrateAmount { use dex_pallet::HigherPrecisionBalance; @@ -472,76 +413,6 @@ mod pallet { )?; Self::increase_allocation(network, account, amount, true) } - - fn can_slash_serai_validator(validator: Public) -> bool { - // Checks if they're active or actively deallocating (letting us still slash them) - // We could check if they're upcoming/still allocating, yet that'd mean the equivocation is - // invalid (as they aren't actively signing anything) or severely dated - // It's not an edge case worth being comprehensive to due to the complexity of being so - Babe::::is_member(&BabeAuthorityId::from(validator)) || - PendingDeallocations::::iter_prefix((NetworkId::Serai, validator)).next().is_some() - } - - fn slash_serai_validator(validator: Public) { - let network = NetworkId::Serai; - - let mut allocation = Abstractions::::get_allocation((network, validator)) - .unwrap_or(Amount(0)); - // reduce the current allocation to 0. - Abstractions::::set_allocation(network, validator, Amount(0)); - - // Take the pending deallocation from the current session - allocation.0 += PendingDeallocations::::take( - (network, validator), - Self::session_to_unlock_on_for_current_set(network).unwrap(), - ) - .unwrap_or(Amount(0)) - .0; - - // Reduce the TotalAllocatedStake for the network, if in set - // TotalAllocatedStake is the sum of allocations and pending deallocations from the current - // session, since pending deallocations can still be slashed and therefore still contribute - // to economic security, hence the allocation calculations above being above and the ones - // below being below - if InSet::::contains_key(NetworkId::Serai, validator) { - let current_staked = Self::total_allocated_stake(network).unwrap(); - TotalAllocatedStake::::set(network, Some(current_staked - allocation)); - } - - // Clear any other pending deallocations. - for (_, pending) in PendingDeallocations::::drain_prefix((network, validator)) { - allocation.0 += pending.0; - } - - // burn the allocation from the stake account - Coins::::burn( - RawOrigin::Signed(Self::account()).into(), - Balance { coin: Coin::Serai, amount: allocation }, - ) - .unwrap(); - } - - /// Disable a Serai validator, preventing them from further authoring blocks. - /// - /// Returns true if the validator-to-disable was actually a validator. - /// Returns false if they weren't. - fn disable_serai_validator(validator: Public) -> bool { - if let Some(index) = - Babe::::authorities().into_iter().position(|(id, _)| id.into_inner() == validator) - { - SeraiDisabledIndices::::set(u32::try_from(index).unwrap(), Some(validator)); - - let session = Self::session(NetworkId::Serai).unwrap(); - Self::deposit_event(Event::ParticipantRemoved { - set: ValidatorSet { network: NetworkId::Serai, session }, - removed: validator, - }); - - true - } else { - false - } - } */ } @@ -633,7 +504,7 @@ mod pallet { #[pallet::call] impl Pallet { - /* + /* TODO #[pallet::call_index(0)] #[pallet::weight((0, DispatchClass::Operational))] // TODO pub fn set_keys( @@ -761,7 +632,7 @@ mod pallet { } } - /* + /* TODO #[pallet::validate_unsigned] impl ValidateUnsigned for Pallet { type Call = Call; @@ -881,107 +752,6 @@ mod pallet { staked.0 >= new_required } } - - impl + From> KeyOwnerProofSystem<(KeyTypeId, V)> for - Pallet { - type Proof = MembershipProof; - type IdentificationTuple = Public; - - fn prove(key: (KeyTypeId, V)) -> Option { - Some(MembershipProof(key.1.into(), PhantomData)) - } - - fn check_proof(key: (KeyTypeId, V), proof: Self::Proof) -> Option { - let validator = key.1.into(); - - // check the offender and the proof offender are the same. - if validator != proof.0 { - return None; - } - - // check validator is valid - if !Self::can_slash_serai_validator(validator) { - return None; - } - - Some(validator) - } - } - - impl ReportOffence> for Pallet { - /// Report an `offence` and reward given `reporters`. - fn report_offence( - _: Vec, - offence: BabeEquivocationOffence, - ) -> Result<(), OffenceError> { - // slash the offender - let offender = offence.offender; - Self::slash_serai_validator(offender); - - // disable it - Self::disable_serai_validator(offender); - - Ok(()) - } - - fn is_known_offence( - offenders: &[Public], - _: & as Offence>::TimeSlot, - ) -> bool { - for offender in offenders { - // It's not a known offence if we can still slash them - if Self::can_slash_serai_validator(*offender) { - return false; - } - } - true - } - } - - impl ReportOffence> for Pallet { - /// Report an `offence` and reward given `reporters`. - fn report_offence( - _: Vec, - offence: GrandpaEquivocationOffence, - ) -> Result<(), OffenceError> { - // slash the offender - let offender = offence.offender; - Self::slash_serai_validator(offender); - - // disable it - Self::disable_serai_validator(offender); - - Ok(()) - } - - fn is_known_offence( - offenders: &[Public], - _slot: & as Offence>::TimeSlot, - ) -> bool { - for offender in offenders { - if Self::can_slash_serai_validator(*offender) { - return false; - } - } - true - } - } - - impl FindAuthor for Pallet { - fn find_author<'a, I>(digests: I) -> Option - where - I: 'a + IntoIterator, - { - let i = Babe::::find_author(digests)?; - Some(Babe::::authorities()[i as usize].0.clone().into()) - } - } - - impl DisabledValidators for Pallet { - fn is_disabled(index: u32) -> bool { - SeraiDisabledIndices::::get(index).is_some() - } - } */ } pub use pallet::*;