Skip to content

Commit 13e6fa7

Browse files
committed
WIP add peras cert to ShelleyBlock and adapt serialization test suite
1 parent 1a40463 commit 13e6fa7

File tree

4 files changed

+158
-62
lines changed
  • ouroboros-consensus-cardano/src
  • ouroboros-consensus/src/unstable-consensus-testlib/Test/Util/Serialisation

4 files changed

+158
-62
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ module Ouroboros.Consensus.Shelley.Eras
2828

2929
-- * Convenience functions
3030
, isBeforeConway
31+
, isBeforeDijkstra
3132

3233
-- * Re-exports
3334
, StandardCrypto
@@ -140,6 +141,10 @@ isBeforeConway :: forall era. L.Era era => Proxy era -> Bool
140141
isBeforeConway _ =
141142
L.eraProtVerLow @era < L.eraProtVerLow @L.ConwayEra
142143

144+
isBeforeDijkstra :: forall era. L.Era era => Proxy era -> Bool
145+
isBeforeDijkstra _ =
146+
L.eraProtVerLow @era < L.eraProtVerLow @L.DijkstraEra
147+
143148
-- | The default implementation of 'applyShelleyBasedTx', a thin wrapper around
144149
-- 'SL.applyTx'
145150
defaultApplyShelleyBasedTx ::

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

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
{-# LANGUAGE GADTs #-}
77
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
88
{-# LANGUAGE MultiParamTypeClasses #-}
9+
{-# LANGUAGE OverloadedStrings #-}
910
{-# LANGUAGE ScopedTypeVariables #-}
1011
{-# LANGUAGE StandaloneDeriving #-}
1112
{-# LANGUAGE TypeApplications #-}
@@ -29,6 +30,7 @@ module Ouroboros.Consensus.Shelley.Ledger.Block
2930
, fromShelleyBlock
3031
, toShelleyBlock
3132
, mkShelleyBlock
33+
, mkShelleyBlockWithPerasCert
3234
, mkShelleyHeader
3335

3436
-- * Serialisation
@@ -48,7 +50,12 @@ import Cardano.Ledger.Binary
4850
( Annotator (..)
4951
, DecCBOR (..)
5052
, EncCBOR (..)
53+
, EncCBORGroup (..)
5154
, FullByteString (..)
55+
, cborError
56+
, decodeListLen
57+
, encodeListLen
58+
, fromPlainDecoder
5259
, serialize
5360
)
5461
import qualified Cardano.Ledger.Binary.Plain as Plain
@@ -63,9 +70,11 @@ import Cardano.Ledger.Hashes (HASH)
6370
import qualified Cardano.Ledger.Shelley.API as SL
6471
import Cardano.Protocol.Crypto (Crypto)
6572
import qualified Cardano.Protocol.TPraos.BHeader as SL
73+
import Codec.Serialise (Serialise (..))
6674
import Control.Arrow (Arrow (..))
6775
import qualified Data.ByteString.Lazy as Lazy
6876
import Data.Coerce (coerce)
77+
import Data.Maybe.Strict (StrictMaybe (..))
6978
import Data.Typeable (Typeable)
7079
import GHC.Generics (Generic)
7180
import NoThunks.Class (NoThunks (..))
@@ -151,6 +160,7 @@ instance ShelleyCompatible proto era => ConvertRawHash (ShelleyBlock proto era)
151160
data ShelleyBlock proto era = ShelleyBlock
152161
{ shelleyBlockHeader :: !(ShelleyProtocolHeader proto)
153162
, shelleyBlockBody :: !(SL.BlockBody era)
163+
, shelleyBlockPerasCert :: !(StrictMaybe (PerasCert (ShelleyBlock proto era)))
154164
, shelleyBlockHeaderHash :: !ShelleyHash
155165
}
156166

@@ -181,10 +191,27 @@ mkShelleyBlock ::
181191
ShelleyProtocolHeader proto ->
182192
SL.BlockBody era ->
183193
ShelleyBlock proto era
184-
mkShelleyBlock header body =
194+
mkShelleyBlock = mkShelleyBlockGeneric SNothing
195+
196+
mkShelleyBlockWithPerasCert ::
197+
ShelleyCompatible proto era =>
198+
PerasCert (ShelleyBlock proto era) ->
199+
ShelleyProtocolHeader proto ->
200+
SL.BlockBody era ->
201+
ShelleyBlock proto era
202+
mkShelleyBlockWithPerasCert = mkShelleyBlockGeneric . SJust
203+
204+
mkShelleyBlockGeneric ::
205+
ShelleyCompatible proto era =>
206+
StrictMaybe (PerasCert (ShelleyBlock proto era)) ->
207+
ShelleyProtocolHeader proto ->
208+
BlockBody era ->
209+
ShelleyBlock proto era
210+
mkShelleyBlockGeneric cert header body =
185211
ShelleyBlock
186212
{ shelleyBlockHeader = header
187213
, shelleyBlockBody = body
214+
, shelleyBlockPerasCert = cert
188215
, shelleyBlockHeaderHash = pHeaderHash header
189216
}
190217

@@ -308,10 +335,35 @@ instance HasNestedContent f (ShelleyBlock proto era)
308335

309336
instance ShelleyCompatible proto era => EncCBOR (ShelleyBlock proto era) where
310337
-- Don't encode the header hash, we recompute it during deserialisation
311-
encCBOR = encCBOR . fromShelleyBlock
338+
encCBOR block = do
339+
let header = shelleyBlockHeader block
340+
let body = shelleyBlockBody block
341+
let bodyLen = listLen body
342+
case shelleyBlockPerasCert block of
343+
SNothing ->
344+
encodeListLen (1 + bodyLen)
345+
<> encCBOR header
346+
<> encCBORGroup body
347+
SJust cert ->
348+
encodeListLen (1 + bodyLen + 1)
349+
<> encCBOR header
350+
<> encCBORGroup body
351+
<> encCBOR (encode cert)
312352

313353
instance ShelleyCompatible proto era => DecCBOR (Annotator (ShelleyBlock proto era)) where
314-
decCBOR = fmap toShelleyBlock <$> decCBOR
354+
decCBOR = do
355+
len <- decodeListLen
356+
header <- decCBOR
357+
body <- decCBOR
358+
cert <- decMaybeCertOrFail len
359+
pure $ mkShelleyBlockGeneric <$> cert <*> header <*> body
360+
where
361+
bodyLen = fromIntegral (numSegComponents @era)
362+
363+
decMaybeCertOrFail len
364+
| len == 1 + bodyLen = pure <$> pure SNothing
365+
| len == 1 + bodyLen + 1 = pure <$> (SJust <$> fromPlainDecoder decode)
366+
| otherwise = cborError $ Plain.DecoderErrorCustom "ShelleyBlock" "invalid number of elements"
315367

316368
instance ShelleyCompatible proto era => EncCBOR (Header (ShelleyBlock proto era)) where
317369
-- Don't encode the header hash, we recompute it during deserialisation
@@ -362,7 +414,7 @@ decodeShelleyHeader = eraDecoder @era $ (. Full) . runAnnotator <$> decCBOR
362414
-------------------------------------------------------------------------------}
363415

364416
instance ShelleyCompatible proto era => Condense (ShelleyBlock proto era) where
365-
condense = show . (shelleyBlockHeader &&& shelleyBlockBody)
417+
condense = show . ((shelleyBlockHeader &&& shelleyBlockBody) &&& shelleyBlockPerasCert)
366418

367419
instance ShelleyCompatible proto era => Condense (Header (ShelleyBlock proto era)) where
368420
condense = show . shelleyHeaderRaw

ouroboros-consensus-cardano/src/unstable-shelley-testlib/Test/Consensus/Shelley/Examples.hs

Lines changed: 79 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import Ouroboros.Consensus.Protocol.TPraos
5555
( TPraos
5656
, TPraosState (TPraosState)
5757
)
58+
import Ouroboros.Consensus.Shelley.Eras (isBeforeDijkstra)
5859
import Ouroboros.Consensus.Shelley.HFEras
5960
import Ouroboros.Consensus.Shelley.Ledger
6061
import Ouroboros.Consensus.Shelley.Ledger.Query.Types
@@ -79,8 +80,9 @@ import Test.Cardano.Protocol.TPraos.Examples
7980
import Test.Util.Orphans.Arbitrary ()
8081
import Test.Util.Serialisation.Examples
8182
( Examples (..)
83+
, addLabelSuffix
8284
, labelled
83-
, unlabelled
85+
, maybeLabelled
8486
)
8587
import Test.Util.Serialisation.SomeResult (SomeResult (..))
8688

@@ -120,35 +122,46 @@ mkLedgerTables tx =
120122
xs -> xs
121123

122124
fromShelleyLedgerExamples ::
125+
forall era.
123126
ShelleyCompatible (TPraos StandardCrypto) era =>
124127
ProtocolLedgerExamples (SL.BHeader StandardCrypto) era ->
125128
Examples (ShelleyBlock (TPraos StandardCrypto) era)
126129
fromShelleyLedgerExamples
127130
ProtocolLedgerExamples
128131
{ pleLedgerExamples = Shelley.LedgerExamples{..}
129132
, ..
130-
} =
131-
Examples
132-
{ exampleBlock = unlabelled blk
133-
, exampleSerialisedBlock = unlabelled serialisedBlock
134-
, exampleHeader = unlabelled $ getHeader blk
135-
, exampleSerialisedHeader = unlabelled serialisedHeader
136-
, exampleHeaderHash = unlabelled hash
137-
, exampleGenTx = unlabelled tx
138-
, exampleGenTxId = unlabelled $ txId tx
139-
, exampleApplyTxErr = unlabelled leApplyTxError
140-
, exampleQuery = queries
141-
, exampleResult = results
142-
, exampleAnnTip = unlabelled annTip
143-
, exampleLedgerState = unlabelled ledgerState
144-
, exampleChainDepState = unlabelled chainDepState
145-
, exampleExtLedgerState = unlabelled extLedgerState
146-
, exampleSlotNo = unlabelled slotNo
147-
, exampleLedgerConfig = unlabelled ledgerConfig
148-
, exampleLedgerTables = unlabelled $ mkLedgerTables leTx
149-
}
133+
}
134+
| isBeforeDijkstra (Proxy @era) =
135+
mkExample Nothing blkWithoutCert
136+
| otherwise =
137+
mkExample (Just "WithoutPerasCert") blkWithoutCert
138+
<> mkExample (Just "WithPerasCert") blkWithCert
150139
where
151-
blk = toShelleyBlock pleBlock
140+
mkExample lbl blk =
141+
Examples
142+
{ exampleBlock = maybeLabelled lbl blk
143+
, exampleSerialisedBlock = maybeLabelled lbl serialisedBlock
144+
, exampleHeader = maybeLabelled lbl (getHeader blk)
145+
, exampleSerialisedHeader = maybeLabelled lbl serialisedHeader
146+
, exampleHeaderHash = maybeLabelled lbl hash
147+
, exampleGenTx = maybeLabelled lbl tx
148+
, exampleGenTxId = maybeLabelled lbl (txId tx)
149+
, exampleApplyTxErr = maybeLabelled lbl leApplyTxError
150+
, exampleQuery = maybe queries (flip addLabelSuffix queries) lbl
151+
, exampleResult = maybe results (flip addLabelSuffix results) lbl
152+
, exampleAnnTip = maybeLabelled lbl annTip
153+
, exampleLedgerState = maybeLabelled lbl ledgerState
154+
, exampleChainDepState = maybeLabelled lbl chainDepState
155+
, exampleExtLedgerState = maybeLabelled lbl extLedgerState
156+
, exampleSlotNo = maybeLabelled lbl slotNo
157+
, exampleLedgerConfig = maybeLabelled lbl ledgerConfig
158+
, exampleLedgerTables = maybeLabelled lbl (mkLedgerTables leTx)
159+
}
160+
161+
SL.Block header body = pleBlock
162+
blkWithoutCert = mkShelleyBlock header body
163+
blkWithCert = mkShelleyBlockWithPerasCert perasCert header body
164+
152165
hash = ShelleyHash $ SL.unHashHeader pleHashHeader
153166
serialisedBlock = Serialised "<BLOCK>"
154167
tx = mkShelleyTx leTx
@@ -169,7 +182,7 @@ fromShelleyLedgerExamples
169182
]
170183
results =
171184
labelled
172-
[ ("LedgerTip", SomeResult GetLedgerTip (blockPoint blk))
185+
[ ("LedgerTip", SomeResult GetLedgerTip (blockPoint blkWithoutCert))
173186
, ("EpochNo", SomeResult GetEpochNo (EpochNo 10))
174187
, ("EmptyPParams", SomeResult GetCurrentPParams lePParams)
175188
, ("StakeDistribution", SomeResult GetStakeDistribution $ fromLedgerPoolDistr lePoolDistr)
@@ -228,6 +241,11 @@ fromShelleyLedgerExamples
228241
ExtLedgerState
229242
ledgerState
230243
(genesisHeaderState chainDepState)
244+
perasCert =
245+
PerasCert
246+
{ pcCertRound = PerasRoundNo 10
247+
, pcCertBoostedBlock = blockPoint blkWithoutCert
248+
}
231249

232250
ledgerConfig = exampleShelleyLedgerConfig leTranslationContext
233251

@@ -241,31 +259,39 @@ fromShelleyLedgerExamplesPraos
241259
ProtocolLedgerExamples
242260
{ pleLedgerExamples = Shelley.LedgerExamples{..}
243261
, ..
244-
} =
245-
Examples
246-
{ exampleBlock = unlabelled blk
247-
, exampleSerialisedBlock = unlabelled serialisedBlock
248-
, exampleHeader = unlabelled $ getHeader blk
249-
, exampleSerialisedHeader = unlabelled serialisedHeader
250-
, exampleHeaderHash = unlabelled hash
251-
, exampleGenTx = unlabelled tx
252-
, exampleGenTxId = unlabelled $ txId tx
253-
, exampleApplyTxErr = unlabelled leApplyTxError
254-
, exampleQuery = queries
255-
, exampleResult = results
256-
, exampleAnnTip = unlabelled annTip
257-
, exampleLedgerState = unlabelled ledgerState
258-
, exampleLedgerTables = unlabelled $ mkLedgerTables leTx
259-
, exampleChainDepState = unlabelled chainDepState
260-
, exampleExtLedgerState = unlabelled extLedgerState
261-
, exampleSlotNo = unlabelled slotNo
262-
, exampleLedgerConfig = unlabelled ledgerConfig
263-
}
262+
}
263+
| isBeforeDijkstra (Proxy @era) =
264+
mkExample Nothing blkWithoutCert
265+
| otherwise =
266+
mkExample (Just "WithoutPerasCert") blkWithoutCert
267+
<> mkExample (Just "WithPerasCert") blkWithCert
264268
where
265-
blk =
266-
toShelleyBlock $
267-
let SL.Block hdr1 bdy = pleBlock
268-
in SL.Block (translateHeader hdr1) bdy
269+
mkExample lbl blk =
270+
Examples
271+
{ exampleBlock = maybeLabelled lbl blk
272+
, exampleSerialisedBlock = maybeLabelled lbl serialisedBlock
273+
, exampleHeader = maybeLabelled lbl $ getHeader blk
274+
, exampleSerialisedHeader = maybeLabelled lbl serialisedHeader
275+
, exampleHeaderHash = maybeLabelled lbl hash
276+
, exampleGenTx = maybeLabelled lbl tx
277+
, exampleGenTxId = maybeLabelled lbl $ txId tx
278+
, exampleApplyTxErr = maybeLabelled lbl leApplyTxError
279+
, exampleQuery = maybe queries (flip addLabelSuffix queries) lbl
280+
, exampleResult = maybe results (flip addLabelSuffix results) lbl
281+
, exampleAnnTip = maybeLabelled lbl annTip
282+
, exampleLedgerState = maybeLabelled lbl ledgerState
283+
, exampleLedgerTables = maybeLabelled lbl $ mkLedgerTables leTx
284+
, exampleChainDepState = maybeLabelled lbl chainDepState
285+
, exampleExtLedgerState = maybeLabelled lbl extLedgerState
286+
, exampleSlotNo = maybeLabelled lbl slotNo
287+
, exampleLedgerConfig = maybeLabelled lbl ledgerConfig
288+
}
289+
290+
SL.Block header' body = pleBlock
291+
header = translateHeader header'
292+
293+
blkWithoutCert = mkShelleyBlock header body
294+
blkWithCert = mkShelleyBlockWithPerasCert perasCert header body
269295

270296
translateHeader :: SL.BHeader StandardCrypto -> Praos.Header StandardCrypto
271297
translateHeader (SL.BHeader bhBody bhSig) =
@@ -305,7 +331,7 @@ fromShelleyLedgerExamplesPraos
305331
]
306332
results =
307333
labelled
308-
[ ("LedgerTip", SomeResult GetLedgerTip (blockPoint blk))
334+
[ ("LedgerTip", SomeResult GetLedgerTip (blockPoint blkWithoutCert))
309335
, ("EpochNo", SomeResult GetEpochNo (EpochNo 10))
310336
, ("EmptyPParams", SomeResult GetCurrentPParams lePParams)
311337
, ("StakeDistribution", SomeResult GetStakeDistribution $ fromLedgerPoolDistr lePoolDistr)
@@ -366,6 +392,11 @@ fromShelleyLedgerExamplesPraos
366392
ExtLedgerState
367393
ledgerState
368394
(genesisHeaderState chainDepState)
395+
perasCert =
396+
PerasCert
397+
{ pcCertRound = PerasRoundNo 10
398+
, pcCertBoostedBlock = blockPoint blkWithoutCert
399+
}
369400

370401
ledgerConfig = exampleShelleyLedgerConfig leTranslationContext
371402

ouroboros-consensus/src/unstable-consensus-testlib/Test/Util/Serialisation/Examples.hs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ module Test.Util.Serialisation.Examples
1414
, Labelled
1515
, labelled
1616
, unlabelled
17+
, maybeLabelled
18+
, mapLabel
19+
, addLabelPrefix
20+
, addLabelSuffix
1721
) where
1822

1923
import Data.Bifunctor (first)
@@ -138,16 +142,7 @@ mapExamples f = combineExamples (const f) mempty
138142
-- When a label is empty, the prefix is used as the label. If the label is not
139143
-- empty, the prefix and @_@ are prepended.
140144
prefixExamples :: String -> Examples blk -> Examples blk
141-
prefixExamples prefix = mapExamples addPrefix
142-
where
143-
addPrefix :: Labelled a -> Labelled a
144-
addPrefix l =
145-
[ (Just label, x)
146-
| (mbLabel, x) <- l
147-
, let label = case mbLabel of
148-
Nothing -> prefix
149-
Just lbl -> prefix <> "_" <> lbl
150-
]
145+
prefixExamples prefix = mapExamples (addLabelPrefix prefix)
151146

152147
{-------------------------------------------------------------------------------
153148
Labelling
@@ -160,3 +155,16 @@ unlabelled x = [(Nothing, x)]
160155

161156
labelled :: [(String, a)] -> Labelled a
162157
labelled = map (first Just)
158+
159+
maybeLabelled :: Maybe String -> a -> Labelled a
160+
maybeLabelled Nothing a = unlabelled a
161+
maybeLabelled (Just l) a = labelled [(l, a)]
162+
163+
mapLabel :: String -> (String -> String) -> Labelled a -> Labelled a
164+
mapLabel def f xs = labelled [(maybe def f l, x) | (l, x) <- xs]
165+
166+
addLabelPrefix :: String -> Labelled a -> Labelled a
167+
addLabelPrefix prefix = mapLabel prefix ((prefix <> "_") <>)
168+
169+
addLabelSuffix :: String -> Labelled a -> Labelled a
170+
addLabelSuffix suffix = mapLabel suffix (<> ("_" <> suffix))

0 commit comments

Comments
 (0)