| 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 {}
- newtype TotalStake = TotalStake {}
- 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
newtype NonPersistentCommitteeSize Source #
Non-persistent committee size
Constructors
| NonPersistentCommitteeSize | |
Fields | |
Instances
| FromCBOR NonPersistentCommitteeSize Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| ToCBOR NonPersistentCommitteeSize Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods toCBOR ∷ NonPersistentCommitteeSize → Encoding Source # encodedSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy NonPersistentCommitteeSize → Size Source # encodedListSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy [NonPersistentCommitteeSize] → Size Source # | |||||
| Eq NonPersistentCommitteeSize Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| Generic NonPersistentCommitteeSize Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Associated Types
| |||||
| Show NonPersistentCommitteeSize Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods showsPrec ∷ Int → NonPersistentCommitteeSize → ShowS # | |||||
| NoThunks NonPersistentCommitteeSize Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| type Rep NonPersistentCommitteeSize Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA type Rep NonPersistentCommitteeSize = D1 ('MetaData "NonPersistentCommitteeSize" "Ouroboros.Consensus.Committee.WFA" "ouroboros-consensus-4.0.0.0-inplace" 'True) (C1 ('MetaCons "NonPersistentCommitteeSize" 'PrefixI 'True) (S1 ('MetaSel ('Just "unNonPersistentCommitteeSize") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Word64))) | |||||
newtype TotalPersistentStake Source #
Total persistent stake
Constructors
| TotalPersistentStake | |
Instances
| FromCBOR TotalPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| ToCBOR TotalPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods toCBOR ∷ TotalPersistentStake → Encoding Source # encodedSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy TotalPersistentStake → Size Source # encodedListSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy [TotalPersistentStake] → Size Source # | |||||
| Eq TotalPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods | |||||
| Generic TotalPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Associated Types
Methods | |||||
| Show TotalPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods showsPrec ∷ Int → TotalPersistentStake → ShowS # show ∷ TotalPersistentStake → String # showList ∷ [TotalPersistentStake] → ShowS # | |||||
| NoThunks TotalPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| type Rep TotalPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA type Rep TotalPersistentStake = D1 ('MetaData "TotalPersistentStake" "Ouroboros.Consensus.Committee.WFA" "ouroboros-consensus-4.0.0.0-inplace" 'True) (C1 ('MetaCons "TotalPersistentStake" 'PrefixI 'True) (S1 ('MetaSel ('Just "unTotalPersistentStake") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Cumulative LedgerStake)))) | |||||
newtype TotalNonPersistentStake Source #
Total non-persistent stake
Constructors
| TotalNonPersistentStake | |
Instances
| FromCBOR TotalNonPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| ToCBOR TotalNonPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods toCBOR ∷ TotalNonPersistentStake → Encoding Source # encodedSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy TotalNonPersistentStake → Size Source # encodedListSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy [TotalNonPersistentStake] → Size Source # | |||||
| Eq TotalNonPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| Generic TotalNonPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Associated Types
Methods from ∷ TotalNonPersistentStake → Rep TotalNonPersistentStake x # to ∷ Rep TotalNonPersistentStake x → TotalNonPersistentStake # | |||||
| Show TotalNonPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| NoThunks TotalNonPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| type Rep TotalNonPersistentStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA type Rep TotalNonPersistentStake = D1 ('MetaData "TotalNonPersistentStake" "Ouroboros.Consensus.Committee.WFA" "ouroboros-consensus-4.0.0.0-inplace" 'True) (C1 ('MetaCons "TotalNonPersistentStake" 'PrefixI 'True) (S1 ('MetaSel ('Just "unTotalNonPersistentStake") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Cumulative LedgerStake)))) | |||||
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
| FromCBOR SeatIndex Source # | |||||
| ToCBOR SeatIndex Source # | |||||
| Eq SeatIndex Source # | |||||
| Ord SeatIndex Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| Enum SeatIndex Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| Generic SeatIndex Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Associated Types
| |||||
| 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 # | |||||
| NoThunks SeatIndex Source # | |||||
| type Rep 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
| FromCBOR NumPoolsWithPositiveStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| ToCBOR NumPoolsWithPositiveStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods toCBOR ∷ NumPoolsWithPositiveStake → Encoding Source # encodedSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy NumPoolsWithPositiveStake → Size Source # encodedListSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy [NumPoolsWithPositiveStake] → Size Source # | |||||
| Eq NumPoolsWithPositiveStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| Generic NumPoolsWithPositiveStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Associated Types
| |||||
| Show NumPoolsWithPositiveStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods showsPrec ∷ Int → NumPoolsWithPositiveStake → ShowS # | |||||
| NoThunks NumPoolsWithPositiveStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| type Rep NumPoolsWithPositiveStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA type Rep NumPoolsWithPositiveStake = D1 ('MetaData "NumPoolsWithPositiveStake" "Ouroboros.Consensus.Committee.WFA" "ouroboros-consensus-4.0.0.0-inplace" 'True) (C1 ('MetaCons "NumPoolsWithPositiveStake" 'PrefixI 'True) (S1 ('MetaSel ('Just "unNumPoolsWithPositiveStake") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Word64))) | |||||
newtype TotalStake Source #
Total stake in the underlying stake distribution
Constructors
| TotalStake | |
Fields | |
Instances
| FromCBOR TotalStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| ToCBOR TotalStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods toCBOR ∷ TotalStake → Encoding Source # encodedSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy TotalStake → Size Source # encodedListSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy [TotalStake] → Size Source # | |||||
| Eq TotalStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| Generic TotalStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Associated Types
| |||||
| Show TotalStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods showsPrec ∷ Int → TotalStake → ShowS # show ∷ TotalStake → String # showList ∷ [TotalStake] → ShowS # | |||||
| NoThunks TotalStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| type Rep TotalStake Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA type Rep TotalStake = D1 ('MetaData "TotalStake" "Ouroboros.Consensus.Committee.WFA" "ouroboros-consensus-4.0.0.0-inplace" 'True) (C1 ('MetaCons "TotalStake" 'PrefixI 'True) (S1 ('MetaSel ('Just "unTotalStake") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Cumulative LedgerStake)))) | |||||
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). |
Instances
| FromCBOR WFAError Source # | |||||
| ToCBOR WFAError Source # | |||||
| Eq WFAError Source # | |||||
| Exception WFAError Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods toException ∷ WFAError → SomeException # fromException ∷ SomeException → Maybe WFAError # | |||||
| Generic WFAError Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Associated Types
| |||||
| Show WFAError Source # | |||||
| NoThunks WFAError Source # | |||||
| type Rep WFAError Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA type Rep WFAError = D1 ('MetaData "WFAError" "Ouroboros.Consensus.Committee.WFA" "ouroboros-consensus-4.0.0.0-inplace" 'False) (C1 ('MetaCons "EmptyStakeDistribution" 'PrefixI 'False) (U1 ∷ Type → Type) :+: C1 ('MetaCons "NotEnoughPoolsWithPositiveStake" 'PrefixI 'False) (S1 ('MetaSel ('Nothing ∷ Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 TargetCommitteeSize) :*: S1 ('MetaSel ('Nothing ∷ Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 NumPoolsWithPositiveStake))) | |||||
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
| FromCBOR a ⇒ FromCBOR (ExtWFAStakeDistr a) Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| ToCBOR a ⇒ ToCBOR (ExtWFAStakeDistr a) Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods toCBOR ∷ ExtWFAStakeDistr a → Encoding Source # encodedSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy (ExtWFAStakeDistr a) → Size Source # encodedListSizeExpr ∷ (∀ t. ToCBOR t ⇒ Proxy t → Size) → Proxy [ExtWFAStakeDistr a] → Size Source # | |||||
| Eq a ⇒ Eq (ExtWFAStakeDistr a) Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Methods (==) ∷ ExtWFAStakeDistr a → ExtWFAStakeDistr a → Bool # (/=) ∷ ExtWFAStakeDistr a → ExtWFAStakeDistr a → Bool # | |||||
| Generic (ExtWFAStakeDistr a) Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA Associated Types
Methods from ∷ ExtWFAStakeDistr a → Rep (ExtWFAStakeDistr a) x # to ∷ Rep (ExtWFAStakeDistr a) x → ExtWFAStakeDistr a # | |||||
| 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 # | |||||
| NoThunks a ⇒ NoThunks (ExtWFAStakeDistr a) Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA | |||||
| type Rep (ExtWFAStakeDistr a) Source # | |||||
Defined in Ouroboros.Consensus.Committee.WFA type Rep (ExtWFAStakeDistr a) = D1 ('MetaData "ExtWFAStakeDistr" "Ouroboros.Consensus.Committee.WFA" "ouroboros-consensus-4.0.0.0-inplace" 'False) (C1 ('MetaCons "ExtWFAStakeDistr" 'PrefixI 'True) (S1 ('MetaSel ('Just "unExtWFAStakeDistr") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Array SeatIndex (PoolId, a, LedgerStake, Cumulative LedgerStake))) :*: (S1 ('MetaSel ('Just "numPoolsWithPositiveStake") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 NumPoolsWithPositiveStake) :*: S1 ('MetaSel ('Just "totalStake") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 TotalStake)))) | |||||
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.