mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-18 08:45:00 +00:00
Make InSet a double map
Reduces amount of code, allows removing the custom iter for PrefixIterator.
This commit is contained in:
parent
82f7342372
commit
d1d5ee6b3d
1 changed files with 14 additions and 50 deletions
|
@ -98,46 +98,12 @@ pub mod pallet {
|
||||||
>;
|
>;
|
||||||
/// The validators selected to be in-set, regardless of if removed, with the ability to perform a
|
/// The validators selected to be in-set, regardless of if removed, with the ability to perform a
|
||||||
/// check for presence.
|
/// check for presence.
|
||||||
// Uses Identity so we can call clear_prefix over network, manually inserting a Blake2 hash
|
// Uses Identity for NetworkId to avoid a hash of a severely limited fixed key-space.
|
||||||
// before the spammable key.
|
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
pub(crate) type InSet<T: Config> =
|
pub(crate) type InSet<T: Config> =
|
||||||
StorageMap<_, Identity, (NetworkId, [u8; 16], Public), u64, OptionQuery>;
|
StorageDoubleMap<_, Identity, NetworkId, Blake2_128Concat, Public, u64, OptionQuery>;
|
||||||
|
|
||||||
// TODO: Merge this with SortedAllocationsIter
|
|
||||||
struct InSetIter<T: Config> {
|
|
||||||
_t: PhantomData<T>,
|
|
||||||
prefix: Vec<u8>,
|
|
||||||
last: Vec<u8>,
|
|
||||||
}
|
|
||||||
impl<T: Config> InSetIter<T> {
|
|
||||||
fn new(network: NetworkId) -> Self {
|
|
||||||
let mut prefix = InSet::<T>::final_prefix().to_vec();
|
|
||||||
prefix.extend(&network.encode());
|
|
||||||
Self { _t: PhantomData, prefix: prefix.clone(), last: prefix }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T: Config> Iterator for InSetIter<T> {
|
|
||||||
type Item = u64;
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let next = sp_io::storage::next_key(&self.last)?;
|
|
||||||
if !next.starts_with(&self.prefix) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let res = u64::decode(&mut sp_io::storage::get(&next).unwrap().as_ref()).unwrap();
|
|
||||||
self.last = next;
|
|
||||||
Some(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Config> Pallet<T> {
|
impl<T: Config> Pallet<T> {
|
||||||
fn in_set_key(
|
|
||||||
network: NetworkId,
|
|
||||||
account: T::AccountId,
|
|
||||||
) -> (NetworkId, [u8; 16], T::AccountId) {
|
|
||||||
(network, sp_io::hashing::blake2_128(&(network, account).encode()), account)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This exists as InSet, for Serai, is the validators set for the next session, *not* the
|
// This exists as InSet, for Serai, is the validators set for the next session, *not* the
|
||||||
// current set's validators
|
// current set's validators
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -153,7 +119,7 @@ pub mod pallet {
|
||||||
if network == NetworkId::Serai {
|
if network == NetworkId::Serai {
|
||||||
Self::in_active_serai_set(account)
|
Self::in_active_serai_set(account)
|
||||||
} else {
|
} else {
|
||||||
InSet::<T>::contains_key(Self::in_set_key(network, account))
|
InSet::<T>::contains_key(network, account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +127,7 @@ pub mod pallet {
|
||||||
///
|
///
|
||||||
/// This will still include participants which were removed from the DKG.
|
/// This will still include participants which were removed from the DKG.
|
||||||
pub fn in_set(network: NetworkId, account: Public) -> bool {
|
pub fn in_set(network: NetworkId, account: Public) -> bool {
|
||||||
if InSet::<T>::contains_key(Self::in_set_key(network, account)) {
|
if InSet::<T>::contains_key(network, account) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +143,7 @@ pub mod pallet {
|
||||||
/// This is useful when working with `allocation` and `total_allocated_stake`, which return the
|
/// This is useful when working with `allocation` and `total_allocated_stake`, which return the
|
||||||
/// latest information.
|
/// latest information.
|
||||||
pub fn in_latest_decided_set(network: NetworkId, account: Public) -> bool {
|
pub fn in_latest_decided_set(network: NetworkId, account: Public) -> bool {
|
||||||
InSet::<T>::contains_key(Self::in_set_key(network, account))
|
InSet::<T>::contains_key(network, account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +224,8 @@ pub mod pallet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Doesn't use PrefixIterator as we need to yield the keys *and* values
|
||||||
|
// PrefixIterator only yields the values
|
||||||
struct SortedAllocationsIter<T: Config> {
|
struct SortedAllocationsIter<T: Config> {
|
||||||
_t: PhantomData<T>,
|
_t: PhantomData<T>,
|
||||||
prefix: Vec<u8>,
|
prefix: Vec<u8>,
|
||||||
|
@ -347,14 +315,10 @@ pub mod pallet {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clear the current InSet
|
// Clear the current InSet
|
||||||
{
|
assert_eq!(
|
||||||
let mut in_set_key = InSet::<T>::final_prefix().to_vec();
|
InSet::<T>::clear_prefix(network, MAX_KEY_SHARES_PER_SET, None).maybe_cursor,
|
||||||
in_set_key.extend(network.encode());
|
None
|
||||||
assert!(matches!(
|
);
|
||||||
sp_io::storage::clear_prefix(&in_set_key, Some(MAX_KEY_SHARES_PER_SET)),
|
|
||||||
sp_io::KillStorageResult::AllRemoved(_)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let allocation_per_key_share = Self::allocation_per_key_share(network).unwrap().0;
|
let allocation_per_key_share = Self::allocation_per_key_share(network).unwrap().0;
|
||||||
|
|
||||||
|
@ -366,7 +330,7 @@ pub mod pallet {
|
||||||
let Some((key, amount)) = iter.next() else { break };
|
let Some((key, amount)) = iter.next() else { break };
|
||||||
|
|
||||||
let these_key_shares = amount.0 / allocation_per_key_share;
|
let these_key_shares = amount.0 / allocation_per_key_share;
|
||||||
InSet::<T>::set(Self::in_set_key(network, key), Some(these_key_shares));
|
InSet::<T>::set(network, key, Some(these_key_shares));
|
||||||
participants.push((key, these_key_shares));
|
participants.push((key, these_key_shares));
|
||||||
|
|
||||||
// This can technically set key_shares to a value exceeding MAX_KEY_SHARES_PER_SET
|
// This can technically set key_shares to a value exceeding MAX_KEY_SHARES_PER_SET
|
||||||
|
@ -540,7 +504,7 @@ pub mod pallet {
|
||||||
Err(Error::<T>::AllocationWouldPreventFaultTolerance)?;
|
Err(Error::<T>::AllocationWouldPreventFaultTolerance)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if InSet::<T>::contains_key(Self::in_set_key(network, account)) {
|
if InSet::<T>::contains_key(network, account) {
|
||||||
TotalAllocatedStake::<T>::set(
|
TotalAllocatedStake::<T>::set(
|
||||||
network,
|
network,
|
||||||
Some(Amount(TotalAllocatedStake::<T>::get(network).unwrap_or(Amount(0)).0 + amount.0)),
|
Some(Amount(TotalAllocatedStake::<T>::get(network).unwrap_or(Amount(0)).0 + amount.0)),
|
||||||
|
@ -967,7 +931,7 @@ pub mod pallet {
|
||||||
// This is done by iterating over InSet, which isn't mutated on removal, and reading the
|
// This is done by iterating over InSet, which isn't mutated on removal, and reading the
|
||||||
// shares from that
|
// shares from that
|
||||||
let mut all_key_shares = 0;
|
let mut all_key_shares = 0;
|
||||||
for shares in InSetIter::<T>::new(*network) {
|
for shares in InSet::<T>::iter_prefix_values(network) {
|
||||||
all_key_shares += shares;
|
all_key_shares += shares;
|
||||||
}
|
}
|
||||||
// 2f + 1
|
// 2f + 1
|
||||||
|
|
Loading…
Reference in a new issue