mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Incorporate check a validator won't prevent ever not having a single point of failure
This commit is contained in:
@@ -319,21 +319,6 @@ mod pallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
fn increase_allocation(
|
|
||||||
network: NetworkId,
|
|
||||||
account: T::AccountId,
|
|
||||||
amount: Amount,
|
|
||||||
block_reward: bool,
|
|
||||||
) -> DispatchResult {
|
|
||||||
/* TODO
|
|
||||||
// The above is_bft calls are only used to check a BFT net doesn't become non-BFT
|
|
||||||
// Check here if this call would prevent a non-BFT net from *ever* becoming BFT
|
|
||||||
if (new_allocation / allocation_per_key_share) >= (MAX_KEY_SHARES_PER_SET_U32 / 3).into() {
|
|
||||||
Err(Error::<T>::AllocationWouldPreventFaultTolerance)?;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
fn session_to_unlock_on_for_current_set(network: NetworkId) -> Option<Session> {
|
fn session_to_unlock_on_for_current_set(network: NetworkId) -> Option<Session> {
|
||||||
let mut to_unlock_on = Self::session(network)?;
|
let mut to_unlock_on = Self::session(network)?;
|
||||||
// Move to the next session, as deallocating currently in-use stake is obviously invalid
|
// Move to the next session, as deallocating currently in-use stake is obviously invalid
|
||||||
|
|||||||
@@ -366,37 +366,45 @@ impl<Storage: SessionsStorage> Sessions for Storage {
|
|||||||
Err(AllocationError::AllocationLessThanKeyShare)?
|
Err(AllocationError::AllocationLessThanKeyShare)?
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
If the validator set has a single point of failure, the following does nothing. If the
|
|
||||||
validator set has decentralized and doesn't have a single point of failure, the following
|
|
||||||
will ensure this allocation doesn't create a single point of failure.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
// Check the validator set's current expected key shares
|
let new_key_shares =
|
||||||
let expected_key_shares = Self::expected_key_shares(network, allocation_per_key_share);
|
KeySharesStruct::from_allocation(new_allocation, allocation_per_key_share);
|
||||||
// Check if the top validator in this set may be faulty without causing a halt under this f
|
|
||||||
let currently_tolerates_single_point_of_failure = if let Some(top_validator) =
|
// If this would guarantee this validator will be a single point of failure, error
|
||||||
Self::iter_allocations(network, allocation_per_key_share).next()
|
if ((3 * new_key_shares.0) + 1) > KeySharesStruct::MAX_PER_SET {
|
||||||
|
Err(AllocationError::IntroducesSinglePointOfFailure)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If the validator set has a single point of failure, the following does nothing. If the
|
||||||
|
validator set has decentralized and doesn't have a single point of failure, the following
|
||||||
|
will ensure this allocation doesn't create a single point of failure.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
let (_key, amount) = top_validator;
|
// Check the validator set's current expected key shares
|
||||||
let key_shares = KeySharesStruct::from_allocation(amount, allocation_per_key_share);
|
let expected_key_shares = Self::expected_key_shares(network, allocation_per_key_share);
|
||||||
key_shares.0 <= (expected_key_shares.0 / 3)
|
// Check if the top validator in this set may be faulty without causing a halt under this f
|
||||||
} else {
|
let currently_tolerates_single_point_of_failure = if let Some(top_validator) =
|
||||||
false
|
Self::iter_allocations(network, allocation_per_key_share).next()
|
||||||
};
|
{
|
||||||
// If the set currently tolerates the fault of the top validator, don't let that change
|
let (_key, amount) = top_validator;
|
||||||
if currently_tolerates_single_point_of_failure {
|
let key_shares = KeySharesStruct::from_allocation(amount, allocation_per_key_share);
|
||||||
let old_key_shares =
|
key_shares.0 <= (expected_key_shares.0 / 3)
|
||||||
KeySharesStruct::from_allocation(old_allocation, allocation_per_key_share);
|
} else {
|
||||||
let new_key_shares =
|
false
|
||||||
KeySharesStruct::from_allocation(new_allocation, allocation_per_key_share);
|
};
|
||||||
// Update the amount of expected key shares per the key shares added
|
// If the set currently tolerates the fault of the top validator, don't let that change
|
||||||
let expected_key_shares = KeySharesStruct::saturating_from(
|
if currently_tolerates_single_point_of_failure {
|
||||||
expected_key_shares.0 + (new_key_shares.0 - old_key_shares.0),
|
let old_key_shares =
|
||||||
);
|
KeySharesStruct::from_allocation(old_allocation, allocation_per_key_share);
|
||||||
// If the new key shares exceeds the fault tolerance, don't allow the allocation
|
// Update the amount of expected key shares per the key shares added
|
||||||
if new_key_shares.0 > (expected_key_shares.0 / 3) {
|
let expected_key_shares = KeySharesStruct::saturating_from(
|
||||||
Err(AllocationError::IntroducesSinglePointOfFailure)?
|
expected_key_shares.0 + (new_key_shares.0 - old_key_shares.0),
|
||||||
|
);
|
||||||
|
// If the new key shares exceeds the fault tolerance, don't allow the allocation
|
||||||
|
if new_key_shares.0 > (expected_key_shares.0 / 3) {
|
||||||
|
Err(AllocationError::IntroducesSinglePointOfFailure)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user