| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Ouroboros.Consensus.Committee.WFA
Description
Deterministic portion of the Weighted Fait-Accompli committee selection scheme
Synopsis
- newtype PersistentCommitteeSize = PersistentCommitteeSize {}
- newtype NonPersistentCommitteeSize = NonPersistentCommitteeSize {}
- newtype TotalPersistentStake = TotalPersistentStake {}
- newtype TotalNonPersistentStake = TotalNonPersistentStake {}
- weightedFaitAccompliSplitSeats ∷ ExtWFAStakeDistr c → TargetCommitteeSize → Either WFAError (PersistentCommitteeSize, NonPersistentCommitteeSize, TotalPersistentStake, TotalNonPersistentStake)
- isAbovePersistentSeatThreshold ∷ TargetCommitteeSize → SeatIndex → LedgerStake → Cumulative LedgerStake → Bool
- newtype SeatIndex = SeatIndex {}
- newtype NumPoolsWithPositiveStake = NumPoolsWithPositiveStake {}
- data WFAError
- newtype WFATiebreaker = WFATiebreaker {
- unWFATiebreaker ∷ PoolId → PoolId → Ordering
- wFATiebreakerWithEpochNonce ∷ Nonce → WFATiebreaker
- data ExtWFAStakeDistr a = ExtWFAStakeDistr {}
- mkExtWFAStakeDistr ∷ WFATiebreaker → Map PoolId (LedgerStake, a) → Either WFAError (ExtWFAStakeDistr a)
- getCandidateIfSeatWithinBounds ∷ SeatIndex → ExtWFAStakeDistr a → Maybe (PoolId, a, LedgerStake, Cumulative LedgerStake)
- unsafeGetCandidateInSeat ∷ SeatIndex → ExtWFAStakeDistr a → (PoolId, a, LedgerStake, Cumulative LedgerStake)
Weighted Fait-Accompli committee selection scheme
newtype PersistentCommitteeSize Source #
Persistent committee size
Constructors
| PersistentCommitteeSize | |
Fields | |
Instances
| Show PersistentCommitteeSize Source # | |
Defined in Ouroboros.Consensus.Committee.WFA | |
| Eq PersistentCommitteeSize Source # | |
Defined in Ouroboros.Consensus.Committee.WFA | |
newtype NonPersistentCommitteeSize Source #
Non-persistent committee size
Constructors
| NonPersistentCommitteeSize | |
Fields | |
Instances
| Show NonPersistentCommitteeSize Source # | |
Defined in Ouroboros.Consensus.Committee.WFA Methods showsPrec ∷ Int → NonPersistentCommitteeSize → ShowS # | |
| Eq NonPersistentCommitteeSize Source # | |
Defined in Ouroboros.Consensus.Committee.WFA | |
newtype TotalPersistentStake Source #
Total persistent stake
Constructors
| TotalPersistentStake | |
Instances
| Show TotalPersistentStake Source # | |
Defined in Ouroboros.Consensus.Committee.WFA Methods showsPrec ∷ Int → TotalPersistentStake → ShowS # show ∷ TotalPersistentStake → String # showList ∷ [TotalPersistentStake] → ShowS # | |
| Eq TotalPersistentStake Source # | |
Defined in Ouroboros.Consensus.Committee.WFA Methods | |
newtype TotalNonPersistentStake Source #
Total non-persistent stake
Constructors
| TotalNonPersistentStake | |
Instances
| Show TotalNonPersistentStake Source # | |
Defined in Ouroboros.Consensus.Committee.WFA | |
| Eq TotalNonPersistentStake Source # | |
Defined in Ouroboros.Consensus.Committee.WFA | |
weightedFaitAccompliSplitSeats Source #
Arguments
| ∷ ExtWFAStakeDistr c | Extended cumulative stake distribution of the potential voters |
| → TargetCommitteeSize | Expected total committee size (persistent + non-persistent) |
| → Either WFAError (PersistentCommitteeSize, NonPersistentCommitteeSize, TotalPersistentStake, TotalNonPersistentStake) |
Split a stake distrubution into persistent and non-persistent committee seats according to the weighted Fait-Accompli scheme.
This function returns: * number of persistent seats granted via the weighted Fait-Accompli scheme * number of non-persistent seats expected to vote via local sortition * total persistent stake * total non-persistent stake
isAbovePersistentSeatThreshold Source #
Arguments
| ∷ TargetCommitteeSize | Total committee size (persistent + non-persistent) |
| → SeatIndex | Current voter seat index |
| → LedgerStake | Current voter stake |
| → Cumulative LedgerStake | Cumulated stake of voters with smaller or equal stake (or equal stake but smaller tiebreaker) than the current one |
| → Bool | Whether the current voter has a persistent seat or not |
Evaluate whether a voter with the given stake and relative position in the stake distribution can be granted a persistent seat in the voting committee.
Cumulative stake distributions
Seat index in the voting committee
Constructors
| SeatIndex | |
Fields | |
Instances
| Enum SeatIndex Source # | |
Defined in Ouroboros.Consensus.Committee.WFA | |
| Ix SeatIndex Source # | |
Defined in Ouroboros.Consensus.Committee.WFA Methods range ∷ (SeatIndex, SeatIndex) → [SeatIndex] # index ∷ (SeatIndex, SeatIndex) → SeatIndex → Int # unsafeIndex ∷ (SeatIndex, SeatIndex) → SeatIndex → Int # inRange ∷ (SeatIndex, SeatIndex) → SeatIndex → Bool # rangeSize ∷ (SeatIndex, SeatIndex) → Int # unsafeRangeSize ∷ (SeatIndex, SeatIndex) → Int # | |
| Show SeatIndex Source # | |
| Eq SeatIndex Source # | |
| Ord SeatIndex Source # | |
Defined in Ouroboros.Consensus.Committee.WFA | |
newtype NumPoolsWithPositiveStake Source #
Number of pools with positive stake in the underlying stake distribution
Constructors
| NumPoolsWithPositiveStake | |
Fields | |
Instances
| Show NumPoolsWithPositiveStake Source # | |
Defined in Ouroboros.Consensus.Committee.WFA Methods showsPrec ∷ Int → NumPoolsWithPositiveStake → ShowS # | |
| Eq NumPoolsWithPositiveStake Source # | |
Defined in Ouroboros.Consensus.Committee.WFA | |
Errors that can occur when trying to split the stake distribution into persistent and seats via weighted Fait-Accompli.
Constructors
| EmptyStakeDistribution | The underlying stake distribution is empty |
| NotEnoughPoolsWithPositiveStake TargetCommitteeSize NumPoolsWithPositiveStake | The target committee size is larger than the number of pools with positive stake in the underlying stake distribution, which would lead to incorrect results (e.g. granting persistent seats to voters with zero stake). |
newtype WFATiebreaker Source #
Tiebreaker for voters with the same stake in the cumulative stake.
This is needed to ensure that the cumulative stake distribution is fair with respect to the edge case where there are multiple voters with the same stake around the persistent seat threshold, e.g.:
| seat index | stake | selection outcome | |------------|-------|-------------------| | 0 | 50 | persistent | | 1 | 30 | persistent | | 2 | 20 | persistent | | 3 | 20 | non-persistent | | 4 | 20 | non-persistent | | 5 | 10 | non-persistent | | ... | ... | ... |
In the case above, the pools with seat index 2, 3 and 4 have the same stake, but (under some hypothetical parameterization) only the one with seat index 2 can be granted a persistent seat according to the weighted Fait-Accompli scheme. Then, the job of this tiebreaker is to ensure that the seat index 2 is fairly distributed among the pools with the same stake.
One possible implementation of this tiebreaker is to sort the pools with the
same stake according to the hash of the epoch nonce and the pool ID. This way
the tiebreaker would be deterministic and resilient to manipulation since an
adversary would not be able to predict the epoch nonce in advance
(see wFATiebreakerWithEpochNonce below).
Constructors
| WFATiebreaker | |
Fields
| |
wFATiebreakerWithEpochNonce ∷ Nonce → WFATiebreaker Source #
Fair weighted Fait-Accompli tiebreaker.
For this, we throw the current epoch nonce into the mix to avoid giving an adversary an edge to manipulate the tiebreaking in their favor, as they cannot predict the epoch nonce in advance.
NOTE: this implementation uses BLS-based hashing, but could be replaced by any other cryptographic hash function with similar properties.
data ExtWFAStakeDistr a Source #
Extended cumulative stake distribution.
Stake distribution in descending order with precomputed right-cumulative
stake, i.e., the total stake of voters with smaller or equal stake than the
current one (including the current one itself). In addition, this wrapper
also allows the inclusion of an arbitrary payload of type a. This is useful
to keep track of anything else we might need to know about the voters in the
committee selection scheme (e.g. their public keys) in a single place.
E.g.: given the following stake distribution:
PoolId 1 -> (50, PK#1) PoolId 2 -> (15, PK#2) PoolId 3 -> (10, PK#3) PoolId 4 -> (20, PK#4) PoolId 5 -> (5, PK#5)
We would have the following cumulative stake distribution:
Array.listArray
(SeatIndex 0, SeatIndex 4)
[ (PoolId 1, PK#1, LedgerStake 50, CumulativeStake 100)
, (PoolId 4, PK#4, LedgerStake 20, CumulativeStake 50)
, (PoolId 2, PK#2, LedgerStake 15, CumulativeStake 30)
, (PoolId 3, PK#3, LedgerStake 10, CumulativeStake 15)
, (PoolId 5, PK#5, LedgerStake 5, CumulativeStake 5)
]
NOTE: this wrapper exists to allow us to share the same cumulative stake distribution across multiple committee selection instances derived from the same underlying stake distribution (e.g. Leios and Peras voting committees for the same epoch).
Constructors
| ExtWFAStakeDistr | |
Fields
| |
Instances
| Show a ⇒ Show (ExtWFAStakeDistr a) Source # | |
Defined in Ouroboros.Consensus.Committee.WFA Methods showsPrec ∷ Int → ExtWFAStakeDistr a → ShowS # show ∷ ExtWFAStakeDistr a → String # showList ∷ [ExtWFAStakeDistr a] → ShowS # | |
mkExtWFAStakeDistr ∷ WFATiebreaker → Map PoolId (LedgerStake, a) → Either WFAError (ExtWFAStakeDistr a) Source #
Construct an extended cumulative stake distribution.
Returns an error if the underlying stake distribution is empty.
getCandidateIfSeatWithinBounds ∷ SeatIndex → ExtWFAStakeDistr a → Maybe (PoolId, a, LedgerStake, Cumulative LedgerStake) Source #
Retrieve the candidate information associated to a given seat index, if the seat index is within bounds in the stake distribution.
unsafeGetCandidateInSeat ∷ SeatIndex → ExtWFAStakeDistr a → (PoolId, a, LedgerStake, Cumulative LedgerStake) Source #
Same as getCandidateIfSeatWithinBounds, but assumming that the seat index
is within bounds in the stake distribution.