Restore the event to serai-validator-sets-pallet

This commit is contained in:
Luke Parker
2025-09-20 03:42:24 -04:00
parent ffae6753ec
commit ef07253a27
5 changed files with 94 additions and 70 deletions

1
Cargo.lock generated
View File

@@ -9747,6 +9747,7 @@ dependencies = [
"rand_core 0.6.4", "rand_core 0.6.4",
"serai-abi", "serai-abi",
"serai-coins-pallet", "serai-coins-pallet",
"serai-core-pallet",
"sp-api", "sp-api",
"sp-application-crypto", "sp-application-crypto",
"sp-core", "sp-core",

View File

@@ -77,12 +77,24 @@ impl Call {
} }
} }
/// The timeline for a deallocation.
#[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
pub enum DeallocationTimeline {
/// The deallocation is available immediately.
Immediate,
/// The dealocation was delayed.
Delayed {
/// The session the deallocation unlocks at and can be claimed.
unlocks_at: Session,
},
}
/// An event from the validator sets. /// An event from the validator sets.
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] #[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
pub enum Event { pub enum Event {
/// A new validator set was declared. /// A new validator set was decided.
NewSet { SetDecided {
/// The set declared. /// The set decided.
set: ValidatorSet, set: ValidatorSet,
}, },
/// A validator set has set their keys. /// A validator set has set their keys.
@@ -97,10 +109,12 @@ pub enum Event {
/// The set which accepted responsibility from the prior set. /// The set which accepted responsibility from the prior set.
set: ValidatorSet, set: ValidatorSet,
}, },
/// A validator set has retired. /// A validator set their keys on an embedded elliptic curve for a network.
SetRetired { SetEmbeddedEllipticCurveKeys {
/// The set retired. /// The validator which set their keys.
set: ValidatorSet, validator: SeraiAddress,
/// The network which they set embedded elliptic curve keys for.
network: ExternalNetworkId,
}, },
/// A validator's allocation to a network has increased. /// A validator's allocation to a network has increased.
Allocation { Allocation {
@@ -119,13 +133,11 @@ pub enum Event {
network: NetworkId, network: NetworkId,
/// The amount of stake deallocated. /// The amount of stake deallocated.
amount: Amount, amount: Amount,
/// The session which claiming the deallocation was delayed until. /// The timeline for this deallocation.
delayed_until: Option<Session>, timeline: DeallocationTimeline,
}, },
/// A validator's deallocation from a network has been claimed. /// A validator's delayed deallocation from a network has been claimed.
/// DelayedDeallocationClaimed {
/// This is only emited for deallocations which were delayed and has to be explicitly claimed.
DeallocationClaimed {
/// The validator who claimed their deallocation. /// The validator who claimed their deallocation.
validator: SeraiAddress, validator: SeraiAddress,
/// The validator set the deallocation was delayed until. /// The validator set the deallocation was delayed until.

View File

@@ -34,6 +34,7 @@ pallet-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] } serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }
serai-core-pallet = { path = "../core", default-features = false }
serai-coins-pallet = { path = "../coins", default-features = false } serai-coins-pallet = { path = "../coins", default-features = false }
[dev-dependencies] [dev-dependencies]
@@ -63,6 +64,7 @@ std = [
"serai-abi/std", "serai-abi/std",
"serai-core-pallet/std",
"serai-coins-pallet/std", "serai-coins-pallet/std",
] ]
@@ -75,6 +77,9 @@ try-runtime = [
"pallet-session/try-runtime", "pallet-session/try-runtime",
"pallet-babe/try-runtime", "pallet-babe/try-runtime",
"pallet-grandpa/try-runtime", "pallet-grandpa/try-runtime",
"serai-core-pallet/try-runtime",
"serai-coins-pallet/try-runtime",
] ]
runtime-benchmarks = [ runtime-benchmarks = [
@@ -83,6 +88,9 @@ runtime-benchmarks = [
"pallet-babe/runtime-benchmarks", "pallet-babe/runtime-benchmarks",
"pallet-grandpa/runtime-benchmarks", "pallet-grandpa/runtime-benchmarks",
"serai-core-pallet/runtime-benchmarks",
"serai-coins-pallet/runtime-benchmarks",
] ]
default = ["std"] default = ["std"]

View File

@@ -39,8 +39,10 @@ mod pallet {
address::SeraiAddress, address::SeraiAddress,
}, },
economic_security::EconomicSecurity, economic_security::EconomicSecurity,
validator_sets::{DeallocationTimeline, Event},
}; };
use serai_core_pallet::Pallet as Core;
use serai_coins_pallet::Pallet as Coins; use serai_coins_pallet::Pallet as Coins;
use super::*; use super::*;
@@ -51,6 +53,7 @@ mod pallet {
+ pallet_session::Config + pallet_session::Config
+ pallet_babe::Config + pallet_babe::Config
+ pallet_grandpa::Config + pallet_grandpa::Config
+ serai_core_pallet::Config
+ serai_coins_pallet::Config<serai_coins_pallet::CoinsInstance> + serai_coins_pallet::Config<serai_coins_pallet::CoinsInstance>
{ {
type ShouldEndSession: ShouldEndSession<BlockNumberFor<Self>>; type ShouldEndSession: ShouldEndSession<BlockNumberFor<Self>>;
@@ -125,6 +128,8 @@ mod pallet {
StorageDoubleMap<_, Blake2_128Concat, Public, Identity, Session, Amount, OptionQuery>; StorageDoubleMap<_, Blake2_128Concat, Public, Identity, Session, Amount, OptionQuery>;
impl<T: Config> SessionsStorage for Abstractions<T> { impl<T: Config> SessionsStorage for Abstractions<T> {
type Config = T;
type GenesisValidators = GenesisValidators<T>; type GenesisValidators = GenesisValidators<T>;
type AllocationPerKeyShare = AllocationPerKeyShare<T>; type AllocationPerKeyShare = AllocationPerKeyShare<T>;
type CurrentSession = CurrentSession<T>; type CurrentSession = CurrentSession<T>;
@@ -153,44 +158,6 @@ mod pallet {
#[pallet::storage] #[pallet::storage]
pub type PendingSlashReport<T: Config> = pub type PendingSlashReport<T: Config> =
StorageMap<_, Identity, ExternalNetworkId, Public, OptionQuery>; StorageMap<_, Identity, ExternalNetworkId, Public, OptionQuery>;
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
NewSet {
set: ValidatorSet,
},
ParticipantRemoved {
set: ValidatorSet,
removed: T::AccountId,
},
KeyGen {
set: ExternalValidatorSet,
key_pair: KeyPair,
},
AcceptedHandover {
set: ValidatorSet,
},
SetRetired {
set: ValidatorSet,
},
AllocationIncreased {
validator: T::AccountId,
network: NetworkId,
amount: Amount,
},
AllocationDecreased {
validator: T::AccountId,
network: NetworkId,
amount: Amount,
delayed_until: Option<Session>,
},
DeallocationClaimed {
validator: T::AccountId,
network: NetworkId,
session: Session,
},
}
*/ */
#[pallet::error] #[pallet::error]
@@ -541,7 +508,9 @@ mod pallet {
let session = Self::current_session(NetworkId::from(network)) let session = Self::current_session(NetworkId::from(network))
.expect("validated `set_keys` for a non-existent session"); .expect("validated `set_keys` for a non-existent session");
let set = ExternalValidatorSet { network, session }; let set = ExternalValidatorSet { network, session };
Abstractions::<T>::set_keys(set, key_pair); Abstractions::<T>::set_keys(set, key_pair.clone());
Core::<T>::emit_event(Event::SetKeys { set, key_pair });
// If this is the first session of an external network, mark them current, not solely decided // If this is the first session of an external network, mark them current, not solely decided
if session == Session(0) { if session == Session(0) {
@@ -587,11 +556,16 @@ mod pallet {
origin: OriginFor<T>, origin: OriginFor<T>,
keys: SignedEmbeddedEllipticCurveKeys, keys: SignedEmbeddedEllipticCurveKeys,
) -> DispatchResult { ) -> DispatchResult {
let signer = ensure_signed(origin)?; let validator = ensure_signed(origin)?;
let network = keys.network();
<Abstractions<T> as crate::EmbeddedEllipticCurveKeys>::set_embedded_elliptic_curve_keys( <Abstractions<T> as crate::EmbeddedEllipticCurveKeys>::set_embedded_elliptic_curve_keys(
signer, keys, validator, keys,
) )
.map_err(|()| Error::<T>::InvalidEmbeddedEllipticCurveKeys)?; .map_err(|()| Error::<T>::InvalidEmbeddedEllipticCurveKeys)?;
Core::<T>::emit_event(Event::SetEmbeddedEllipticCurveKeys {
validator: validator.into(),
network,
});
Ok(()) Ok(())
} }
@@ -612,14 +586,22 @@ mod pallet {
#[pallet::call_index(4)] #[pallet::call_index(4)]
#[pallet::weight((0, DispatchClass::Normal))] // TODO #[pallet::weight((0, DispatchClass::Normal))] // TODO
pub fn deallocate(origin: OriginFor<T>, network: NetworkId, amount: Amount) -> DispatchResult { pub fn deallocate(origin: OriginFor<T>, network: NetworkId, amount: Amount) -> DispatchResult {
let account = ensure_signed(origin)?; let validator = ensure_signed(origin)?;
let deallocation_timeline = Abstractions::<T>::decrease_allocation(network, account, amount) let timeline = Abstractions::<T>::decrease_allocation(network, validator, amount)
.map_err(Error::<T>::DeallocationError)?; .map_err(Error::<T>::DeallocationError)?;
if matches!(deallocation_timeline, DeallocationTimeline::Immediate) {
Core::<T>::emit_event(Event::Deallocation {
validator: validator.into(),
network,
amount,
timeline,
});
if matches!(timeline, DeallocationTimeline::Immediate) {
Coins::<T, serai_coins_pallet::CoinsInstance>::transfer_fn( Coins::<T, serai_coins_pallet::CoinsInstance>::transfer_fn(
Self::account(), Self::account(),
account, validator,
Balance { coin: Coin::Serai, amount }, Balance { coin: Coin::Serai, amount },
)?; )?;
} }
@@ -634,12 +616,18 @@ mod pallet {
network: NetworkId, network: NetworkId,
session: Session, session: Session,
) -> DispatchResult { ) -> DispatchResult {
let account = ensure_signed(origin)?; let validator = ensure_signed(origin)?;
let amount = Abstractions::<T>::claim_delayed_deallocation(account, network, session) let amount = Abstractions::<T>::claim_delayed_deallocation(validator, network, session)
.map_err(Error::<T>::DeallocationError)?; .map_err(Error::<T>::DeallocationError)?;
Core::<T>::emit_event(Event::DelayedDeallocationClaimed {
validator: validator.into(),
deallocation: ValidatorSet { network, session },
});
Coins::<T, serai_coins_pallet::CoinsInstance>::transfer_fn( Coins::<T, serai_coins_pallet::CoinsInstance>::transfer_fn(
Self::account(), Self::account(),
account, validator,
Balance { coin: Coin::Serai, amount }, Balance { coin: Coin::Serai, amount },
)?; )?;
Ok(()) Ok(())

View File

@@ -1,14 +1,19 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use sp_core::{Encode, Decode, ConstU32, sr25519::Public, bounded::BoundedVec}; use sp_core::{Encode, Decode, ConstU32, sr25519::Public, bounded::BoundedVec};
use serai_abi::primitives::{ use serai_abi::{
network_id::NetworkId, primitives::{
balance::Amount, network_id::NetworkId,
validator_sets::{KeyShares as KeySharesStruct, Session, ExternalValidatorSet, ValidatorSet}, balance::Amount,
validator_sets::{KeyShares as KeySharesStruct, Session, ExternalValidatorSet, ValidatorSet},
},
validator_sets::{DeallocationTimeline, Event},
}; };
use frame_support::storage::{StorageValue, StorageMap, StorageDoubleMap, StoragePrefixedMap}; use frame_support::storage::{StorageValue, StorageMap, StorageDoubleMap, StoragePrefixedMap};
use serai_core_pallet::Pallet as Core;
use crate::{ use crate::{
embedded_elliptic_curve_keys::EmbeddedEllipticCurveKeys, allocations::Allocations, keys::Keys, embedded_elliptic_curve_keys::EmbeddedEllipticCurveKeys, allocations::Allocations, keys::Keys,
}; };
@@ -21,6 +26,9 @@ pub(crate) type GenesisValidators =
pub(crate) type SelectedValidatorsKey = (ValidatorSet, [u8; 16], Public); pub(crate) type SelectedValidatorsKey = (ValidatorSet, [u8; 16], Public);
pub(crate) trait SessionsStorage: EmbeddedEllipticCurveKeys + Allocations + Keys { pub(crate) trait SessionsStorage: EmbeddedEllipticCurveKeys + Allocations + Keys {
/// The configuration for the core pallet.
type Config: serai_core_pallet::Config;
/// The genesis validators /// The genesis validators
/// ///
/// The usage of is shared with the rest of the pallet. `Sessions` only reads it. /// The usage of is shared with the rest of the pallet. `Sessions` only reads it.
@@ -119,11 +127,6 @@ pub enum AllocationError {
IntroducesSinglePointOfFailure, IntroducesSinglePointOfFailure,
} }
pub(crate) enum DeallocationTimeline {
Immediate,
Delayed { unlocks_at: Session },
}
/// An error when deallocating. /// An error when deallocating.
#[derive( #[derive(
scale::Encode, scale::Decode, scale::DecodeWithMemTracking, frame_support::PalletError, scale::Encode, scale::Decode, scale::DecodeWithMemTracking, frame_support::PalletError,
@@ -313,6 +316,8 @@ impl<Storage: SessionsStorage> Sessions for Storage {
); );
} }
Core::<Storage::Config>::emit_event(Event::SetDecided { set: latest_decided_set });
true true
} }
@@ -355,6 +360,10 @@ impl<Storage: SessionsStorage> Sessions for Storage {
} }
} }
} }
Core::<Storage::Config>::emit_event(Event::AcceptedHandover {
set: ValidatorSet { network, session: current },
});
} }
fn increase_allocation( fn increase_allocation(
@@ -437,6 +446,12 @@ impl<Storage: SessionsStorage> Sessions for Storage {
} }
} }
Core::<Storage::Config>::emit_event(Event::Allocation {
validator: validator.into(),
network,
amount,
});
Ok(()) Ok(())
} }