Skip to content

Commit 5dc9e03

Browse files
committed
Add Peras cert to ShelleyBlock and adapt CBOR encoder/decoder
1 parent 1a40463 commit 5dc9e03

File tree

1 file changed

+56
-4
lines changed
  • ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger

1 file changed

+56
-4
lines changed

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

0 commit comments

Comments
 (0)