Skip to content

Commit d6e5dfd

Browse files
committed
Refactor: SelectView = BlockNo × TiebreakerView
1 parent 34a5f5b commit d6e5dfd

File tree

27 files changed

+255
-269
lines changed

27 files changed

+255
-269
lines changed

ouroboros-consensus-cardano/src/byron/Ouroboros/Consensus/Byron/Ledger/PBFT.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ instance BlockSupportsProtocol ByronBlock where
7474
where
7575
epochSlots = byronEpochSlots cfg
7676

77-
selectView _ = mkPBftSelectView
77+
tiebreakerView _ = mkPBftTiebreakerView
7878

7979
toPBftLedgerView :: Delegation.Map -> PBftLedgerView PBftByronCrypto
8080
toPBftLedgerView = PBftLedgerView . Delegation.unMap

ouroboros-consensus-cardano/src/ouroboros-consensus-cardano/Ouroboros/Consensus/Cardano/CanHardFork.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ import Ouroboros.Consensus.Protocol.PBFT.State (PBftState)
8282
import qualified Ouroboros.Consensus.Protocol.PBFT.State as PBftState
8383
import Ouroboros.Consensus.Protocol.Praos (Praos)
8484
import qualified Ouroboros.Consensus.Protocol.Praos as Praos
85+
import Ouroboros.Consensus.Protocol.Praos.Common (PraosTiebreakerView)
8586
import Ouroboros.Consensus.Protocol.TPraos
8687
import qualified Ouroboros.Consensus.Protocol.TPraos as TPraos
8788
import Ouroboros.Consensus.Shelley.HFEras ()
@@ -164,10 +165,10 @@ instance CardanoHardForkConstraints c => CanHardFork (CardanoEras c) where
164165
}
165166
hardForkChainSel =
166167
-- Byron <-> Shelley, ...
167-
TCons (SOP.hpure CompareBlockNo)
168+
TCons (SOP.hpure NoTiebreakerAcrossEras)
168169
-- Inter-Shelley-based
169170
$
170-
Tails.hcpure (Proxy @(HasPraosSelectView c)) CompareSameSelectView
171+
Tails.hcpure (Proxy @(HasPraosTiebreakerView c)) SameTiebreakerAcrossEras
171172
hardForkInjectTxs =
172173
PCons (ignoringBoth $ Pair2 cannotInjectTx cannotInjectValidatedTx)
173174
$ PCons
@@ -233,8 +234,8 @@ instance CardanoHardForkConstraints c => CanHardFork (CardanoEras c) where
233234
fromAlonzo x = fromConway $ ConwayMeasure x mempty
234235
fromConway x = x
235236

236-
class SelectView (BlockProtocol blk) ~ PraosChainSelectView c => HasPraosSelectView c blk
237-
instance SelectView (BlockProtocol blk) ~ PraosChainSelectView c => HasPraosSelectView c blk
237+
class TiebreakerView (BlockProtocol blk) ~ PraosTiebreakerView c => HasPraosTiebreakerView c blk
238+
instance TiebreakerView (BlockProtocol blk) ~ PraosTiebreakerView c => HasPraosTiebreakerView c blk
238239

239240
{-------------------------------------------------------------------------------
240241
Translation from Byron to Shelley

ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Block.hs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,8 @@ import Ouroboros.Consensus.HardFork.Combinator
7171
)
7272
import Ouroboros.Consensus.HeaderValidation
7373
import Ouroboros.Consensus.Protocol.Abstract
74-
( ChainDepState
75-
, SelectView
76-
)
7774
import Ouroboros.Consensus.Protocol.Praos.Common
78-
( PraosChainSelectView
75+
( PraosTiebreakerView
7976
)
8077
import Ouroboros.Consensus.Protocol.Signed (SignedHeader)
8178
import Ouroboros.Consensus.Shelley.Eras
@@ -119,7 +116,7 @@ class
119116
, Show (SL.TranslationContext era)
120117
, -- Currently the chain select view is identical
121118
-- Era and proto crypto must coincide
122-
SelectView proto ~ PraosChainSelectView (ProtoCrypto proto)
119+
TiebreakerView proto ~ PraosTiebreakerView (ProtoCrypto proto)
123120
, -- Need to be able to sign the protocol header
124121
SignedHeader (ShelleyProtocolHeader proto)
125122
, -- ChainDepState needs to be serialisable

ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Protocol.hs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ module Ouroboros.Consensus.Shelley.Ledger.Protocol () where
1111

1212
import qualified Cardano.Ledger.Shelley.API as SL
1313
import Ouroboros.Consensus.Block
14+
import Ouroboros.Consensus.Protocol.Praos.Common
1415
import Ouroboros.Consensus.Protocol.Signed
15-
import Ouroboros.Consensus.Protocol.TPraos
1616
import Ouroboros.Consensus.Shelley.Ledger.Block
1717
import Ouroboros.Consensus.Shelley.Ledger.Config (BlockConfig (..))
1818
import Ouroboros.Consensus.Shelley.Protocol.Abstract
@@ -30,13 +30,12 @@ import Ouroboros.Consensus.Shelley.Protocol.Abstract
3030
instance ShelleyCompatible proto era => BlockSupportsProtocol (ShelleyBlock proto era) where
3131
validateView _cfg = protocolHeaderView @proto . shelleyHeaderRaw
3232

33-
selectView _ hdr@(ShelleyHeader shdr _) =
34-
PraosChainSelectView
35-
{ csvChainLength = blockNo hdr
36-
, csvSlotNo = blockSlot hdr
37-
, csvIssuer = hdrIssuer
38-
, csvIssueNo = pHeaderIssueNo shdr
39-
, csvTieBreakVRF = pTieBreakVRFValue shdr
33+
tiebreakerView _ hdr@(ShelleyHeader shdr _) =
34+
PraosTiebreakerView
35+
{ ptvSlotNo = blockSlot hdr
36+
, ptvIssuer = hdrIssuer
37+
, ptvIssueNo = pHeaderIssueNo shdr
38+
, ptvTieBreakVRF = pTieBreakVRFValue shdr
4039
}
4140
where
4241
hdrIssuer :: SL.VKey 'SL.BlockIssuer

ouroboros-consensus-cardano/src/unstable-cardano-testlib/Test/ThreadNet/Infra/ShelleyBasedHardFork.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ instance
271271
, translateTxOutWith = SL.upgradeTxOut
272272
}
273273

274-
hardForkChainSel = Tails.mk2 CompareSameSelectView
274+
hardForkChainSel = Tails.mk2 SameTiebreakerAcrossEras
275275

276276
hardForkInjectTxs =
277277
InPairs.mk2 $

ouroboros-consensus-cardano/test/cardano-test/Test/Consensus/Cardano/DiffusionPipelining.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import Ouroboros.Consensus.Byron.Ledger (ByronBlock)
2222
import Ouroboros.Consensus.Cardano (CardanoBlock)
2323
import Ouroboros.Consensus.HardFork.Combinator
2424
import Ouroboros.Consensus.HardFork.Combinator.AcrossEras
25+
import Ouroboros.Consensus.Protocol.Abstract
2526
import Ouroboros.Consensus.Protocol.PBFT
2627
import Ouroboros.Consensus.Shelley.Eras
2728
import Ouroboros.Consensus.Shelley.Ledger
@@ -79,7 +80,7 @@ instance GenTentativeHeaderViews ByronBlock where
7980
nubOrd . sort <$> listOf do
8081
bno <- arbitrary
8182
isEBB <- toIsEBB <$> arbitrary
82-
pure $ PBftSelectView bno isEBB
83+
pure $ SelectView bno (PBftTiebreakerView isEBB)
8384

8485
instance ShelleyCompatible proto era => GenTentativeHeaderViews (ShelleyBlock proto era) where
8586
genTentativeHeaderViews _ = do

ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ instance CanHardFork '[BlockA, BlockB] where
441441
, translateChainDepState = PCons chainDepState_AtoB PNil
442442
, crossEraForecast = PCons forecast_AtoB PNil
443443
}
444-
hardForkChainSel = Tails.mk2 CompareBlockNo
444+
hardForkChainSel = Tails.mk2 NoTiebreakerAcrossEras
445445
hardForkInjectTxs = InPairs.mk2 injectTx_AtoB
446446

447447
hardForkInjTxMeasure = \case

ouroboros-consensus-protocol/src/ouroboros-consensus-protocol/Ouroboros/Consensus/Protocol/Praos.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ instance PraosCrypto c => ConsensusProtocol (Praos c) where
392392
type ChainDepState (Praos c) = PraosState
393393
type IsLeader (Praos c) = PraosIsLeader c
394394
type CanBeLeader (Praos c) = PraosCanBeLeader c
395-
type SelectView (Praos c) = PraosChainSelectView c
395+
type TiebreakerView (Praos c) = PraosTiebreakerView c
396396
type LedgerView (Praos c) = Views.LedgerView
397397
type ValidationErr (Praos c) = PraosValidationErr c
398398
type ValidateView (Praos c) = PraosValidateView c

ouroboros-consensus-protocol/src/ouroboros-consensus-protocol/Ouroboros/Consensus/Protocol/Praos/Common.hs

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module Ouroboros.Consensus.Protocol.Praos.Common
1111
( MaxMajorProtVer (..)
1212
, HasMaxMajorProtVer (..)
1313
, PraosCanBeLeader (..)
14-
, PraosChainSelectView (..)
14+
, PraosTiebreakerView (..)
1515
, VRFTiebreakerFlavor (..)
1616

1717
-- * node support
@@ -27,7 +27,6 @@ import Cardano.Ledger.Keys (KeyHash, KeyRole (BlockIssuer))
2727
import qualified Cardano.Ledger.Shelley.API as SL
2828
import Cardano.Protocol.Crypto (Crypto, VRF)
2929
import qualified Cardano.Protocol.TPraos.OCert as OCert
30-
import Cardano.Slotting.Block (BlockNo)
3130
import Cardano.Slotting.Slot (SlotNo)
3231
import Data.Function (on)
3332
import Data.Map.Strict (Map)
@@ -66,13 +65,13 @@ newtype MaxMajorProtVer = MaxMajorProtVer
6665
class HasMaxMajorProtVer proto where
6766
protoMaxMajorPV :: ConsensusConfig proto -> MaxMajorProtVer
6867

69-
-- | View of the tip of a header fragment for chain selection.
70-
data PraosChainSelectView c = PraosChainSelectView
71-
{ csvChainLength :: BlockNo
72-
, csvSlotNo :: SlotNo
73-
, csvIssuer :: SL.VKey 'SL.BlockIssuer
74-
, csvIssueNo :: Word64
75-
, csvTieBreakVRF :: VRF.OutputVRF (VRF c)
68+
-- | View of the tip of a header fragment for deciding between chains of equal
69+
-- length.
70+
data PraosTiebreakerView c = PraosTiebreakerView
71+
{ ptvSlotNo :: SlotNo
72+
, ptvIssuer :: SL.VKey 'SL.BlockIssuer
73+
, ptvIssueNo :: Word64
74+
, ptvTieBreakVRF :: VRF.OutputVRF (VRF c)
7675
}
7776
deriving (Show, Eq, Generic, NoThunks)
7877

@@ -107,13 +106,12 @@ data VRFTiebreakerFlavor
107106
-- Used to implement the 'Ord' and 'ChainOrder' instances for Praos.
108107
comparePraos ::
109108
VRFTiebreakerFlavor ->
110-
PraosChainSelectView c ->
111-
PraosChainSelectView c ->
109+
PraosTiebreakerView c ->
110+
PraosTiebreakerView c ->
112111
Ordering
113112
comparePraos tiebreakerFlavor =
114-
(compare `on` csvChainLength)
115-
<> when' issueNoArmed (compare `on` csvIssueNo)
116-
<> when' vrfArmed (compare `on` Down . csvTieBreakVRF)
113+
when' issueNoArmed (compare `on` ptvIssueNo)
114+
<> when' vrfArmed (compare `on` Down . ptvTieBreakVRF)
117115
where
118116
-- When the predicate @p@ returns 'True', use the given comparison function,
119117
-- otherwise, no preference.
@@ -127,57 +125,53 @@ comparePraos tiebreakerFlavor =
127125
-- Only compare the issue numbers when the issuers and slots are identical.
128126
-- Note that this case implies the VRFs also coincide.
129127
issueNoArmed v1 v2 =
130-
csvSlotNo v1 == csvSlotNo v2
131-
&& csvIssuer v1 == csvIssuer v2
128+
ptvSlotNo v1 == ptvSlotNo v2
129+
&& ptvIssuer v1 == ptvIssuer v2
132130

133131
-- Whether to do a VRF comparison.
134132
vrfArmed v1 v2 = case tiebreakerFlavor of
135133
UnrestrictedVRFTiebreaker -> True
136134
RestrictedVRFTiebreaker maxDist ->
137-
slotDist (csvSlotNo v1) (csvSlotNo v2) <= maxDist
135+
slotDist (ptvSlotNo v1) (ptvSlotNo v2) <= maxDist
138136

139137
slotDist :: SlotNo -> SlotNo -> SlotNo
140138
slotDist s t
141139
-- slot numbers are unsigned, so have to take care with subtraction
142140
| s >= t = s - t
143141
| otherwise = t - s
144142

145-
-- | We order between chains as follows:
143+
-- | We order between chains of equal length as follows:
146144
--
147-
-- 1. By chain length, with longer chains always preferred.
148-
--
149-
-- 2. If the tip of each chain was issued by the same agent and they have the
145+
-- 1. If the tip of each chain was issued by the same agent and they have the
150146
-- same slot number, prefer the chain whose tip has the highest ocert issue
151147
-- number.
152148
--
153-
-- 3. By a VRF value from the chain tip, with lower values preferred. See
149+
-- 2. By a VRF value from the chain tip, with lower values preferred. See
154150
-- @pTieBreakVRFValue@ for which one is used.
155151
--
156152
-- IMPORTANT: This is not a complete picture of the Praos chain order, do also
157153
-- consult the documentation of 'ChainOrder'.
158-
instance Crypto c => Ord (PraosChainSelectView c) where
154+
instance Crypto c => Ord (PraosTiebreakerView c) where
159155
compare = comparePraos UnrestrictedVRFTiebreaker
160156

161157
-- | IMPORTANT: This is not a 'SimpleChainOrder'; rather, there are
162-
-- 'PraosChainSelectView's @a, b@ such that @a < b@, but @'not' $
158+
-- 'PraosTiebreakerView's @a, b@ such that @a < b@, but @'not' $
163159
-- 'preferCandidate' cfg a b@, namely for @cfg = 'RestrictedVRFTiebreaker'@.
164160
--
165161
-- === Rules
166162
--
167-
-- Concretely, we have @'preferCandidate' cfg ours cand@ based on the following
168-
-- lexicographical criteria:
169-
--
170-
-- 1. Chain length, with longer chains always preferred.
163+
-- Concretely, we have @'preferCandidate' cfg ours cand@ (where @ours@ and
164+
-- @cand@ have equal length) based on the following lexicographical criteria:
171165
--
172-
-- 2. If the tip of each chain was issued by the same agent and had the same
166+
-- 1. If the tip of each chain was issued by the same agent and had the same
173167
-- slot number, then we prefer the candidate if it has a higher ocert issue
174168
-- number.
175169
--
176170
-- Note that this condition is equivalent to the VRFs being identical, as
177171
-- the VRF is a deterministic function of the issuer VRF key, the slot and
178172
-- the epoch nonce, and VRFs are collision-resistant.
179173
--
180-
-- 3. Depending on the 'VRFTiebreakerFlavor':
174+
-- 2. Depending on the 'VRFTiebreakerFlavor':
181175
--
182176
-- * If 'UnrestrictedVRFTiebreaker': Compare via a VRF value from the chain
183177
-- tip, with lower values preferred. See @pTieBreakVRFValue@ for which one
@@ -190,8 +184,7 @@ instance Crypto c => Ord (PraosChainSelectView c) where
190184
--
191185
-- When using @cfg = 'RestrictedVRFTiebreaker' maxDist@, the chain order is not
192186
-- transitive. As an example, suppose @maxDist = 5@ and consider three
193-
-- 'PraosChainSelectView's with the same chain length and pairwise different
194-
-- issuers and, as well as
187+
-- 'PraosTiebreakerView's with pairwise different issuers and, as well as
195188
--
196189
-- +------+---+---+---+
197190
-- | | a | b | c |
@@ -206,10 +199,7 @@ instance Crypto c => Ord (PraosChainSelectView c) where
206199
--
207200
-- === Rationale for the rules
208201
--
209-
-- 1. The abstract Consensus layer requires that we first compare based on chain
210-
-- length (see __Chain extension precedence__ in 'ChainOrder').
211-
--
212-
-- 2. Consider the scenario where the hot key of a block issuer was compromised,
202+
-- 1. Consider the scenario where the hot key of a block issuer was compromised,
213203
-- and the attacker is now minting blocks using that identity. The actual
214204
-- block issuer can use their cold key to issue a new hot key with a higher
215205
-- opcert issue number and set up a new pool. Due to this tiebreaker rule,
@@ -224,7 +214,7 @@ instance Crypto c => Ord (PraosChainSelectView c) where
224214
-- Specification for Delegation and Incentives in Cardano" by Kant et al for
225215
-- more context.
226216
--
227-
-- 3. The main motivation to do VRF comparisons is to avoid the "Frankfurt
217+
-- 2. The main motivation to do VRF comparisons is to avoid the "Frankfurt
228218
-- problem":
229219
--
230220
-- With only the first two rules for the chain order, almost all blocks with
@@ -244,8 +234,8 @@ instance Crypto c => Ord (PraosChainSelectView c) where
244234
--
245235
-- See 'VRFTiebreakerFlavor' for more context on the exact conditions under
246236
-- which the VRF comparison takes place.
247-
instance Crypto c => ChainOrder (PraosChainSelectView c) where
248-
type ChainOrderConfig (PraosChainSelectView c) = VRFTiebreakerFlavor
237+
instance Crypto c => ChainOrder (PraosTiebreakerView c) where
238+
type ChainOrderConfig (PraosTiebreakerView c) = VRFTiebreakerFlavor
249239

250240
preferCandidate cfg ours cand = comparePraos cfg ours cand == LT
251241

ouroboros-consensus-protocol/src/ouroboros-consensus-protocol/Ouroboros/Consensus/Protocol/TPraos.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
-- schedule determining slots to be produced by BFT
1717
module Ouroboros.Consensus.Protocol.TPraos
1818
( MaxMajorProtVer (..)
19-
, PraosChainSelectView (..)
2019
, TPraos
2120
, TPraosFields (..)
2221
, TPraosIsLeader (..)
@@ -308,7 +307,7 @@ instance SL.PraosCrypto c => ConsensusProtocol (TPraos c) where
308307
type ChainDepState (TPraos c) = TPraosState
309308
type IsLeader (TPraos c) = TPraosIsLeader c
310309
type CanBeLeader (TPraos c) = PraosCanBeLeader c
311-
type SelectView (TPraos c) = PraosChainSelectView c
310+
type TiebreakerView (TPraos c) = PraosTiebreakerView c
312311
type LedgerView (TPraos c) = SL.LedgerView
313312
type ValidationErr (TPraos c) = SL.ChainTransitionError c
314313
type ValidateView (TPraos c) = TPraosValidateView c

0 commit comments

Comments
 (0)