diff --git a/substrate/validator-sets/src/lib.rs b/substrate/validator-sets/src/lib.rs index 39ef2d59..b9ddca12 100644 --- a/substrate/validator-sets/src/lib.rs +++ b/substrate/validator-sets/src/lib.rs @@ -725,7 +725,7 @@ mod pallet { impl Pallet { /* #[pallet::call_index(0)] - #[pallet::weight(0)] // TODO + #[pallet::weight((0, DispatchClass::Operational))] // TODO pub fn set_keys( origin: OriginFor, network: ExternalNetworkId, @@ -758,7 +758,7 @@ mod pallet { } #[pallet::call_index(1)] - #[pallet::weight(0)] // TODO + #[pallet::weight((0, DispatchClass::Operational))] // TODO pub fn report_slashes( origin: OriginFor, network: ExternalNetworkId, @@ -787,7 +787,7 @@ mod pallet { */ #[pallet::call_index(2)] - #[pallet::weight(0)] // TODO + #[pallet::weight((0, DispatchClass::Normal))] // TODO pub fn set_embedded_elliptic_curve_keys( origin: OriginFor, keys: serai_primitives::crypto::SignedEmbeddedEllipticCurveKeys, @@ -801,7 +801,7 @@ mod pallet { } #[pallet::call_index(3)] - #[pallet::weight(0)] // TODO + #[pallet::weight((0, DispatchClass::Normal))] // TODO pub fn allocate(origin: OriginFor, network: NetworkId, amount: Amount) -> DispatchResult { let validator = ensure_signed(origin)?; Coins::::transfer_fn(validator, Self::account(), Balance { coin: Coin::Serai, amount })?; @@ -811,7 +811,7 @@ mod pallet { } #[pallet::call_index(4)] - #[pallet::weight(0)] // TODO + #[pallet::weight((0, DispatchClass::Normal))] // TODO pub fn deallocate(origin: OriginFor, network: NetworkId, amount: Amount) -> DispatchResult { let account = ensure_signed(origin)?; @@ -824,27 +824,19 @@ mod pallet { Ok(()) } - /* #[pallet::call_index(5)] - #[pallet::weight((0, DispatchClass::Operational))] // TODO + #[pallet::weight((0, DispatchClass::Normal))] // TODO pub fn claim_deallocation( origin: OriginFor, network: NetworkId, session: Session, ) -> DispatchResult { let account = ensure_signed(origin)?; - let Some(amount) = Self::take_deallocatable_amount(network, session, account) else { - Err(Error::::NonExistentDeallocation)? - }; - Coins::::transfer_fn( - Self::account(), - account, - Balance { coin: Coin::Serai, amount }, - )?; - Self::deposit_event(Event::DeallocationClaimed { validator: account, network, session }); + let amount = Abstractions::::claim_delayed_deallocation(account, network, session) + .map_err(Error::::DeallocationError)?; + Coins::::transfer_fn(Self::account(), account, Balance { coin: Coin::Serai, amount })?; Ok(()) } - */ } /* diff --git a/substrate/validator-sets/src/sessions.rs b/substrate/validator-sets/src/sessions.rs index 6824bc44..f1a3aa5a 100644 --- a/substrate/validator-sets/src/sessions.rs +++ b/substrate/validator-sets/src/sessions.rs @@ -123,6 +123,10 @@ pub enum DeallocationError { NotEnoughAllocated, /// The remaining allocation was non-zero and would be less than a key share. RemainingAllocationLessThanKeyShare, + /// The delay has yet to be satisfied. + DelayNotSatisfied, + /// No delayed deallocation was present. + NoDelayedDeallocation, } pub(crate) trait Sessions { @@ -164,6 +168,16 @@ pub(crate) trait Sessions { validator: Public, amount: Amount, ) -> Result; + + /// Claim a delayed allocation. + /// + /// This does not perform any transfers of any coins/tokens. It solely performs the book-keeping + /// of it. + fn claim_delayed_deallocation( + validator: Public, + network: NetworkId, + session: Session, + ) -> Result; } impl Sessions for Storage { @@ -432,4 +446,18 @@ impl Sessions for Storage { // immediately handle the deallocation Ok(DeallocationTimeline::Immediate) } + + fn claim_delayed_deallocation( + validator: Public, + network: NetworkId, + session: Session, + ) -> Result { + if Storage::CurrentSession::get(network).map(|session| session.0) < + Some(session).map(|session| session.0) + { + Err(DeallocationError::DelayNotSatisfied)?; + } + Storage::DelayedDeallocations::take(validator, session) + .ok_or(DeallocationError::NoDelayedDeallocation) + } }