diff --git a/Cargo.lock b/Cargo.lock index bad575e2..50fd9134 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9747,6 +9747,7 @@ dependencies = [ "rand_core 0.6.4", "serai-abi", "serai-coins-pallet", + "serai-core-pallet", "sp-api", "sp-application-crypto", "sp-core", diff --git a/substrate/abi/src/validator_sets.rs b/substrate/abi/src/validator_sets.rs index 73f467fc..673aa60b 100644 --- a/substrate/abi/src/validator_sets.rs +++ b/substrate/abi/src/validator_sets.rs @@ -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. #[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] pub enum Event { - /// A new validator set was declared. - NewSet { - /// The set declared. + /// A new validator set was decided. + SetDecided { + /// The set decided. set: ValidatorSet, }, /// A validator set has set their keys. @@ -97,10 +109,12 @@ pub enum Event { /// The set which accepted responsibility from the prior set. set: ValidatorSet, }, - /// A validator set has retired. - SetRetired { - /// The set retired. - set: ValidatorSet, + /// A validator set their keys on an embedded elliptic curve for a network. + SetEmbeddedEllipticCurveKeys { + /// The validator which set their keys. + validator: SeraiAddress, + /// The network which they set embedded elliptic curve keys for. + network: ExternalNetworkId, }, /// A validator's allocation to a network has increased. Allocation { @@ -119,13 +133,11 @@ pub enum Event { network: NetworkId, /// The amount of stake deallocated. amount: Amount, - /// The session which claiming the deallocation was delayed until. - delayed_until: Option, + /// The timeline for this deallocation. + timeline: DeallocationTimeline, }, - /// A validator's deallocation from a network has been claimed. - /// - /// This is only emited for deallocations which were delayed and has to be explicitly claimed. - DeallocationClaimed { + /// A validator's delayed deallocation from a network has been claimed. + DelayedDeallocationClaimed { /// The validator who claimed their deallocation. validator: SeraiAddress, /// The validator set the deallocation was delayed until. diff --git a/substrate/validator-sets/Cargo.toml b/substrate/validator-sets/Cargo.toml index fc1b44c2..c1d182da 100644 --- a/substrate/validator-sets/Cargo.toml +++ b/substrate/validator-sets/Cargo.toml @@ -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-core-pallet = { path = "../core", default-features = false } serai-coins-pallet = { path = "../coins", default-features = false } [dev-dependencies] @@ -63,6 +64,7 @@ std = [ "serai-abi/std", + "serai-core-pallet/std", "serai-coins-pallet/std", ] @@ -75,6 +77,9 @@ try-runtime = [ "pallet-session/try-runtime", "pallet-babe/try-runtime", "pallet-grandpa/try-runtime", + + "serai-core-pallet/try-runtime", + "serai-coins-pallet/try-runtime", ] runtime-benchmarks = [ @@ -83,6 +88,9 @@ runtime-benchmarks = [ "pallet-babe/runtime-benchmarks", "pallet-grandpa/runtime-benchmarks", + + "serai-core-pallet/runtime-benchmarks", + "serai-coins-pallet/runtime-benchmarks", ] default = ["std"] diff --git a/substrate/validator-sets/src/lib.rs b/substrate/validator-sets/src/lib.rs index 378b7571..b5ffad64 100644 --- a/substrate/validator-sets/src/lib.rs +++ b/substrate/validator-sets/src/lib.rs @@ -39,8 +39,10 @@ mod pallet { address::SeraiAddress, }, economic_security::EconomicSecurity, + validator_sets::{DeallocationTimeline, Event}, }; + use serai_core_pallet::Pallet as Core; use serai_coins_pallet::Pallet as Coins; use super::*; @@ -51,6 +53,7 @@ mod pallet { + pallet_session::Config + pallet_babe::Config + pallet_grandpa::Config + + serai_core_pallet::Config + serai_coins_pallet::Config { type ShouldEndSession: ShouldEndSession>; @@ -125,6 +128,8 @@ mod pallet { StorageDoubleMap<_, Blake2_128Concat, Public, Identity, Session, Amount, OptionQuery>; impl SessionsStorage for Abstractions { + type Config = T; + type GenesisValidators = GenesisValidators; type AllocationPerKeyShare = AllocationPerKeyShare; type CurrentSession = CurrentSession; @@ -153,44 +158,6 @@ mod pallet { #[pallet::storage] pub type PendingSlashReport = StorageMap<_, Identity, ExternalNetworkId, Public, OptionQuery>; - - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { - 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, - }, - DeallocationClaimed { - validator: T::AccountId, - network: NetworkId, - session: Session, - }, - } */ #[pallet::error] @@ -541,7 +508,9 @@ mod pallet { let session = Self::current_session(NetworkId::from(network)) .expect("validated `set_keys` for a non-existent session"); let set = ExternalValidatorSet { network, session }; - Abstractions::::set_keys(set, key_pair); + Abstractions::::set_keys(set, key_pair.clone()); + + Core::::emit_event(Event::SetKeys { set, key_pair }); // If this is the first session of an external network, mark them current, not solely decided if session == Session(0) { @@ -587,11 +556,16 @@ mod pallet { origin: OriginFor, keys: SignedEmbeddedEllipticCurveKeys, ) -> DispatchResult { - let signer = ensure_signed(origin)?; + let validator = ensure_signed(origin)?; + let network = keys.network(); as crate::EmbeddedEllipticCurveKeys>::set_embedded_elliptic_curve_keys( - signer, keys, + validator, keys, ) .map_err(|()| Error::::InvalidEmbeddedEllipticCurveKeys)?; + Core::::emit_event(Event::SetEmbeddedEllipticCurveKeys { + validator: validator.into(), + network, + }); Ok(()) } @@ -612,14 +586,22 @@ mod pallet { #[pallet::call_index(4)] #[pallet::weight((0, DispatchClass::Normal))] // TODO pub fn deallocate(origin: OriginFor, network: NetworkId, amount: Amount) -> DispatchResult { - let account = ensure_signed(origin)?; + let validator = ensure_signed(origin)?; - let deallocation_timeline = Abstractions::::decrease_allocation(network, account, amount) + let timeline = Abstractions::::decrease_allocation(network, validator, amount) .map_err(Error::::DeallocationError)?; - if matches!(deallocation_timeline, DeallocationTimeline::Immediate) { + + Core::::emit_event(Event::Deallocation { + validator: validator.into(), + network, + amount, + timeline, + }); + + if matches!(timeline, DeallocationTimeline::Immediate) { Coins::::transfer_fn( Self::account(), - account, + validator, Balance { coin: Coin::Serai, amount }, )?; } @@ -634,12 +616,18 @@ mod pallet { network: NetworkId, session: Session, ) -> DispatchResult { - let account = ensure_signed(origin)?; - let amount = Abstractions::::claim_delayed_deallocation(account, network, session) + let validator = ensure_signed(origin)?; + let amount = Abstractions::::claim_delayed_deallocation(validator, network, session) .map_err(Error::::DeallocationError)?; + + Core::::emit_event(Event::DelayedDeallocationClaimed { + validator: validator.into(), + deallocation: ValidatorSet { network, session }, + }); + Coins::::transfer_fn( Self::account(), - account, + validator, Balance { coin: Coin::Serai, amount }, )?; Ok(()) diff --git a/substrate/validator-sets/src/sessions.rs b/substrate/validator-sets/src/sessions.rs index 66876f30..0459c382 100644 --- a/substrate/validator-sets/src/sessions.rs +++ b/substrate/validator-sets/src/sessions.rs @@ -1,14 +1,19 @@ use alloc::vec::Vec; use sp_core::{Encode, Decode, ConstU32, sr25519::Public, bounded::BoundedVec}; -use serai_abi::primitives::{ - network_id::NetworkId, - balance::Amount, - validator_sets::{KeyShares as KeySharesStruct, Session, ExternalValidatorSet, ValidatorSet}, +use serai_abi::{ + primitives::{ + network_id::NetworkId, + balance::Amount, + validator_sets::{KeyShares as KeySharesStruct, Session, ExternalValidatorSet, ValidatorSet}, + }, + validator_sets::{DeallocationTimeline, Event}, }; use frame_support::storage::{StorageValue, StorageMap, StorageDoubleMap, StoragePrefixedMap}; +use serai_core_pallet::Pallet as Core; + use crate::{ 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) trait SessionsStorage: EmbeddedEllipticCurveKeys + Allocations + Keys { + /// The configuration for the core pallet. + type Config: serai_core_pallet::Config; + /// The genesis validators /// /// The usage of is shared with the rest of the pallet. `Sessions` only reads it. @@ -119,11 +127,6 @@ pub enum AllocationError { IntroducesSinglePointOfFailure, } -pub(crate) enum DeallocationTimeline { - Immediate, - Delayed { unlocks_at: Session }, -} - /// An error when deallocating. #[derive( scale::Encode, scale::Decode, scale::DecodeWithMemTracking, frame_support::PalletError, @@ -313,6 +316,8 @@ impl Sessions for Storage { ); } + Core::::emit_event(Event::SetDecided { set: latest_decided_set }); + true } @@ -355,6 +360,10 @@ impl Sessions for Storage { } } } + + Core::::emit_event(Event::AcceptedHandover { + set: ValidatorSet { network, session: current }, + }); } fn increase_allocation( @@ -437,6 +446,12 @@ impl Sessions for Storage { } } + Core::::emit_event(Event::Allocation { + validator: validator.into(), + network, + amount, + }); + Ok(()) }