Skip to content

Commit b97a8eb

Browse files
committed
Include optional Peras certs during block body serialization
This commit tweaks the serialization instance of Dijkstra block bodies to take optional Peras certificates into account. This should be later enhanced with round-trip tests to ensure backwards compatibility.
1 parent 28ee28e commit b97a8eb

File tree

2 files changed

+56
-11
lines changed
  • eras/dijkstra/impl/src/Cardano/Ledger/Dijkstra/BlockBody
  • libs/cardano-ledger-core/src/Cardano/Ledger

2 files changed

+56
-11
lines changed

eras/dijkstra/impl/src/Cardano/Ledger/Dijkstra/BlockBody/Internal.hs

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import Cardano.Ledger.Binary (
4141
Annotator (..),
4242
DecCBOR (..),
4343
EncCBORGroup (..),
44+
decodeListLen,
4445
encCBOR,
4546
encodeFoldableEncoder,
4647
encodeFoldableMapEncoder,
@@ -53,12 +54,15 @@ import Cardano.Ledger.Dijkstra.Era
5354
import Cardano.Ledger.Dijkstra.Tx ()
5455
import Cardano.Ledger.Shelley.BlockBody (auxDataSeqDecoder)
5556
import Control.Monad (unless)
57+
import Data.Bifunctor (Bifunctor (..))
5658
import Data.ByteString (ByteString)
5759
import Data.ByteString.Builder (Builder, shortByteString, toLazyByteString)
5860
import qualified Data.ByteString.Lazy as BSL
5961
import Data.Coerce (coerce)
62+
import Data.Maybe (fromMaybe)
6063
import Data.Maybe.Strict (
6164
StrictMaybe (..),
65+
isSJust,
6266
maybeToStrictMaybe,
6367
strictMaybeToMaybe,
6468
)
@@ -96,6 +100,8 @@ data DijkstraBlockBody era = DijkstraBlockBodyInternal
96100
, dbbTxsIsValidBytes :: BSL.ByteString
97101
-- ^ Bytes representing a set of integers. These are the indices of
98102
-- transactions with 'isValid' == False.
103+
, dbbPerasCertBytes :: Maybe BSL.ByteString
104+
-- ^ Bytes encoding the optional Peras certificate
99105
}
100106
deriving (Generic)
101107

@@ -104,7 +110,7 @@ instance EraBlockBody DijkstraEra where
104110
mkBasicBlockBody = mkBasicBlockBodyDijkstra
105111
txSeqBlockBodyL = txSeqBlockBodyDijkstraL
106112
hashBlockBody = dbbHash
107-
numSegComponents = 4
113+
numSegComponents = 5
108114

109115
mkBasicBlockBodyDijkstra ::
110116
( SafeToHash (TxWits era)
@@ -151,7 +157,7 @@ pattern DijkstraBlockBody ::
151157
StrictMaybe PerasCert ->
152158
DijkstraBlockBody era
153159
pattern DijkstraBlockBody xs mbPerasCert <-
154-
DijkstraBlockBodyInternal xs mbPerasCert _ _ _ _ _
160+
DijkstraBlockBodyInternal xs mbPerasCert _ _ _ _ _ _
155161
where
156162
DijkstraBlockBody txns mbPerasCert =
157163
let version = eraProtVerLow @era
@@ -170,14 +176,23 @@ pattern DijkstraBlockBody xs mbPerasCert <-
170176
fmap originalBytes . view auxDataTxL <$> txns
171177
txSeqIsValids =
172178
serialize version $ encCBOR $ nonValidatingIndices txns
179+
mbPerasCertBytes =
180+
fmap (serialize version) (strictMaybeToMaybe mbPerasCert)
173181
in DijkstraBlockBodyInternal
174182
{ dbbTxs = txns
175183
, dbbPerasCert = mbPerasCert
176-
, dbbHash = hashDijkstraSegWits txSeqBodies txSeqWits txSeqAuxDatas txSeqIsValids
184+
, dbbHash =
185+
hashDijkstraSegWits
186+
txSeqBodies
187+
txSeqWits
188+
txSeqAuxDatas
189+
txSeqIsValids
190+
mbPerasCertBytes
177191
, dbbTxsBodyBytes = txSeqBodies
178192
, dbbTxsWitsBytes = txSeqWits
179193
, dbbTxsAuxDataBytes = txSeqAuxDatas
180194
, dbbTxsIsValidBytes = txSeqIsValids
195+
, dbbPerasCertBytes = mbPerasCertBytes
181196
}
182197

183198
{-# COMPLETE DijkstraBlockBody #-}
@@ -203,12 +218,18 @@ deriving stock instance Eq (Tx TopTx era) => Eq (DijkstraBlockBody era)
203218
--------------------------------------------------------------------------------
204219

205220
instance Era era => EncCBORGroup (DijkstraBlockBody era) where
206-
encCBORGroup (DijkstraBlockBodyInternal _ _ _ bodyBytes witsBytes metadataBytes invalidBytes) =
221+
encCBORGroup blockBody =
207222
encodePreEncoded $
208223
BSL.toStrict $
209-
bodyBytes <> witsBytes <> metadataBytes <> invalidBytes
210-
listLen _ = 4
211-
listLenBound _ = 4
224+
dbbTxsBodyBytes blockBody
225+
<> dbbTxsWitsBytes blockBody
226+
<> dbbTxsAuxDataBytes blockBody
227+
<> dbbTxsIsValidBytes blockBody
228+
<> fromMaybe BSL.empty (dbbPerasCertBytes blockBody)
229+
listLen blockBody =
230+
4 + if isSJust (dbbPerasCert blockBody) then 1 else 0
231+
listLenBound _ =
232+
5
212233

213234
hashDijkstraSegWits ::
214235
BSL.ByteString ->
@@ -219,13 +240,16 @@ hashDijkstraSegWits ::
219240
-- | Bytes for transaction auxiliary datas
220241
BSL.ByteString ->
221242
-- | Bytes for transaction isValid flags
243+
Maybe BSL.ByteString ->
244+
-- | Bytes for optional Peras certificate
222245
Hash HASH EraIndependentBlockBody
223-
hashDijkstraSegWits txSeqBodies txSeqWits txAuxData txSeqIsValids =
246+
hashDijkstraSegWits txSeqBodies txSeqWits txAuxData txSeqIsValids mbPerasCert =
224247
coerce . hashLazy . toLazyByteString $
225248
hashPart txSeqBodies
226249
<> hashPart txSeqWits
227250
<> hashPart txAuxData
228251
<> hashPart txSeqIsValids
252+
<> maybe mempty hashPart mbPerasCert
229253
where
230254
hashLazy :: BSL.ByteString -> Hash HASH ByteString
231255
hashLazy = Hash.hashWith id . BSL.toStrict
@@ -244,6 +268,8 @@ instance
244268
DecCBOR (Annotator (DijkstraBlockBody era))
245269
where
246270
decCBOR = do
271+
len <- decodeListLen
272+
247273
(bodies, bodiesAnn) <- withSlice decCBOR
248274
(wits, witsAnn) <- withSlice decCBOR
249275
let bodiesLength = length bodies
@@ -274,18 +300,28 @@ instance
274300
StrictSeq.forceToStrict $
275301
Seq.zipWith4 dijkstraSegwitTx bodies wits validFlags auxData
276302

277-
let mbPerasCert =
278-
pure SNothing
303+
(mbPerasCert, mbPerasCertAnn) <-
304+
case len of
305+
4 -> return (pure SNothing, pure Nothing)
306+
5 -> bimap (pure . SJust) (fmap Just) <$> withSlice decCBOR
307+
_ -> fail $ "unexpected body length: " <> show len
279308

280309
pure $
281310
DijkstraBlockBodyInternal
282311
<$> txns
283312
<*> mbPerasCert
284-
<*> (hashDijkstraSegWits <$> bodiesAnn <*> witsAnn <*> auxDataAnn <*> isValAnn)
313+
<*> ( hashDijkstraSegWits
314+
<$> bodiesAnn
315+
<*> witsAnn
316+
<*> auxDataAnn
317+
<*> isValAnn
318+
<*> mbPerasCertAnn
319+
)
285320
<*> bodiesAnn
286321
<*> witsAnn
287322
<*> auxDataAnn
288323
<*> isValAnn
324+
<*> mbPerasCertAnn
289325

290326
--------------------------------------------------------------------------------
291327
-- Internal utility functions

libs/cardano-ledger-core/src/Cardano/Ledger/BaseTypes.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,3 +991,12 @@ instance ToKeyValuePairs a => ToJSON (KeyValuePairs a) where
991991
-- NOTE: The real type will be brought from 'cardano-base' once it's ready.
992992
data PerasCert = PerasCert
993993
deriving (Eq, Show, Generic, NoThunks)
994+
995+
instance EncCBOR PerasCert where
996+
encCBOR PerasCert =
997+
encCBOR ()
998+
999+
instance DecCBOR PerasCert where
1000+
decCBOR = do
1001+
() <- decCBOR
1002+
pure PerasCert

0 commit comments

Comments
 (0)