mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-14 15:09:23 +00:00
rebase to develop latest
This commit is contained in:
@@ -70,6 +70,9 @@ std = [
|
||||
"dex-pallet/std",
|
||||
]
|
||||
|
||||
# TODO
|
||||
try-runtime = []
|
||||
|
||||
runtime-benchmarks = [
|
||||
"frame-system/runtime-benchmarks",
|
||||
"frame-support/runtime-benchmarks",
|
||||
|
||||
@@ -124,7 +124,9 @@ pub mod pallet {
|
||||
#[pallet::getter(fn allocation_per_key_share)]
|
||||
pub type AllocationPerKeyShare<T: Config> =
|
||||
StorageMap<_, Identity, NetworkId, Amount, OptionQuery>;
|
||||
/// The validators selected to be in-set.
|
||||
/// The validators selected to be in-set (and their key shares), regardless of if removed.
|
||||
///
|
||||
/// This method allows iterating over all validators and their stake.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn participants_for_latest_decided_set)]
|
||||
pub(crate) type Participants<T: Config> = StorageMap<
|
||||
@@ -134,8 +136,10 @@ pub mod pallet {
|
||||
BoundedVec<(Public, u64), ConstU32<{ MAX_KEY_SHARES_PER_SET }>>,
|
||||
OptionQuery,
|
||||
>;
|
||||
/// The validators selected to be in-set, regardless of if removed, with the ability to perform a
|
||||
/// check for presence.
|
||||
/// The validators selected to be in-set, regardless of if removed.
|
||||
///
|
||||
/// This method allows quickly checking for presence in-set and looking up a validator's key
|
||||
/// shares.
|
||||
// Uses Identity for NetworkId to avoid a hash of a severely limited fixed key-space.
|
||||
#[pallet::storage]
|
||||
pub(crate) type InSet<T: Config> =
|
||||
@@ -364,7 +368,6 @@ pub mod pallet {
|
||||
let allocation_per_key_share = Self::allocation_per_key_share(network).unwrap().0;
|
||||
|
||||
let mut participants = vec![];
|
||||
let mut total_stake = 0;
|
||||
{
|
||||
let mut iter = SortedAllocationsIter::<T>::new(network);
|
||||
let mut key_shares = 0;
|
||||
@@ -376,7 +379,6 @@ pub mod pallet {
|
||||
participants.push((key, these_key_shares));
|
||||
|
||||
key_shares += these_key_shares;
|
||||
total_stake += amount.0;
|
||||
}
|
||||
amortize_excess_key_shares(&mut participants);
|
||||
}
|
||||
@@ -384,7 +386,6 @@ pub mod pallet {
|
||||
for (key, shares) in &participants {
|
||||
InSet::<T>::set(network, key, Some(*shares));
|
||||
}
|
||||
TotalAllocatedStake::<T>::set(network, Some(Amount(total_stake)));
|
||||
|
||||
let set = ValidatorSet { network, session };
|
||||
Pallet::<T>::deposit_event(Event::NewSet { set });
|
||||
@@ -524,11 +525,16 @@ pub mod pallet {
|
||||
Err(Error::<T>::AllocationWouldPreventFaultTolerance)?;
|
||||
}
|
||||
|
||||
if InSet::<T>::contains_key(network, account) {
|
||||
TotalAllocatedStake::<T>::set(
|
||||
network,
|
||||
Some(Amount(TotalAllocatedStake::<T>::get(network).unwrap_or(Amount(0)).0 + amount.0)),
|
||||
);
|
||||
// If they're in the current set, and the current set has completed its handover (so its
|
||||
// currently being tracked by TotalAllocatedStake), update the TotalAllocatedStake
|
||||
if let Some(session) = Self::session(network) {
|
||||
if InSet::<T>::contains_key(network, account) && Self::handover_completed(network, session)
|
||||
{
|
||||
TotalAllocatedStake::<T>::set(
|
||||
network,
|
||||
Some(Amount(TotalAllocatedStake::<T>::get(network).unwrap_or(Amount(0)).0 + amount.0)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -644,8 +650,9 @@ pub mod pallet {
|
||||
// Checks if this session has completed the handover from the prior session.
|
||||
fn handover_completed(network: NetworkId, session: Session) -> bool {
|
||||
let Some(current_session) = Self::session(network) else { return false };
|
||||
// No handover occurs on genesis
|
||||
if current_session.0 == 0 {
|
||||
|
||||
// If the session we've been queried about is old, it must have completed its handover
|
||||
if current_session.0 > session.0 {
|
||||
return true;
|
||||
}
|
||||
// If the session we've been queried about has yet to start, it can't have completed its
|
||||
@@ -653,19 +660,21 @@ pub mod pallet {
|
||||
if current_session.0 < session.0 {
|
||||
return false;
|
||||
}
|
||||
if current_session.0 == session.0 {
|
||||
// Handover is automatically complete for Serai as it doesn't have a handover protocol
|
||||
// If not Serai, check the prior session had its keys cleared, which happens once its
|
||||
// retired
|
||||
return (network == NetworkId::Serai) ||
|
||||
(!Keys::<T>::contains_key(ValidatorSet {
|
||||
network,
|
||||
session: Session(current_session.0 - 1),
|
||||
}));
|
||||
|
||||
// Handover is automatically complete for Serai as it doesn't have a handover protocol
|
||||
if network == NetworkId::Serai {
|
||||
return true;
|
||||
}
|
||||
// We're currently in a future session, meaning this session definitely performed itself
|
||||
// handover
|
||||
true
|
||||
|
||||
// The current session must have set keys for its handover to be completed
|
||||
if !Keys::<T>::contains_key(ValidatorSet { network, session }) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This must be the first session (which has set keys) OR the prior session must have been
|
||||
// retired (signified by its keys no longer being present)
|
||||
(session.0 == 0) ||
|
||||
(!Keys::<T>::contains_key(ValidatorSet { network, session: Session(session.0 - 1) }))
|
||||
}
|
||||
|
||||
fn new_session() {
|
||||
@@ -683,6 +692,17 @@ pub mod pallet {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_total_allocated_stake(network: NetworkId) {
|
||||
let participants = Participants::<T>::get(network)
|
||||
.expect("setting TotalAllocatedStake for a network without participants");
|
||||
let total_stake = participants.iter().fold(0, |acc, (addr, _)| {
|
||||
acc + Allocations::<T>::get((network, addr)).unwrap_or(Amount(0)).0
|
||||
});
|
||||
TotalAllocatedStake::<T>::set(network, Some(Amount(total_stake)));
|
||||
}
|
||||
|
||||
// TODO: This is called retire_set, yet just starts retiring the set
|
||||
// Update the nomenclature within this function
|
||||
pub fn retire_set(set: ValidatorSet) {
|
||||
// If the prior prior set didn't report, emit they're retired now
|
||||
if PendingSlashReport::<T>::get(set.network).is_some() {
|
||||
@@ -691,7 +711,7 @@ pub mod pallet {
|
||||
});
|
||||
}
|
||||
|
||||
// Serai network slashes are handled by BABE/GRANDPA
|
||||
// Serai doesn't set keys and network slashes are handled by BABE/GRANDPA
|
||||
if set.network != NetworkId::Serai {
|
||||
// This overwrites the prior value as the prior to-report set's stake presumably just
|
||||
// unlocked, making their report unenforceable
|
||||
@@ -703,6 +723,9 @@ pub mod pallet {
|
||||
Self::deposit_event(Event::AcceptedHandover {
|
||||
set: ValidatorSet { network: set.network, session: Session(set.session.0 + 1) },
|
||||
});
|
||||
|
||||
// Update the total allocated stake to be for the current set
|
||||
Self::set_total_allocated_stake(set.network);
|
||||
}
|
||||
|
||||
/// Take the amount deallocatable.
|
||||
@@ -890,7 +913,7 @@ pub mod pallet {
|
||||
pub fn set_keys(
|
||||
origin: OriginFor<T>,
|
||||
network: NetworkId,
|
||||
removed_participants: Vec<Public>,
|
||||
removed_participants: BoundedVec<Public, ConstU32<{ MAX_KEY_SHARES_PER_SET / 3 }>>,
|
||||
key_pair: KeyPair,
|
||||
signature: Signature,
|
||||
) -> DispatchResult {
|
||||
@@ -905,6 +928,13 @@ pub mod pallet {
|
||||
|
||||
Keys::<T>::set(set, Some(key_pair.clone()));
|
||||
|
||||
// If this is the first ever set for this network, set TotalAllocatedStake now
|
||||
// We generally set TotalAllocatedStake when the prior set retires, and the new set is fully
|
||||
// active and liable. Since this is the first set, there is no prior set to wait to retire
|
||||
if session == Session(0) {
|
||||
Self::set_total_allocated_stake(network);
|
||||
}
|
||||
|
||||
// This does not remove from TotalAllocatedStake or InSet in order to:
|
||||
// 1) Not decrease the stake present in this set. This means removed participants are
|
||||
// still liable for the economic security of the external network. This prevents
|
||||
|
||||
Reference in New Issue
Block a user