Skip to content

Commit 43ecd64

Browse files
committed
Review remarks
1 parent 80d439d commit 43ecd64

File tree

4 files changed

+53
-61
lines changed

4 files changed

+53
-61
lines changed

cardano-api/src/Cardano/Api/Internal/Serialise/Cbor/Canonical.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,16 @@ import Data.ByteString.Lazy qualified as LBS
2929
import Data.List (sortBy)
3030
import Data.Tuple.Extra (both)
3131

32-
-- | This function implements CBOR canonicalisation:
32+
-- | This function implements CBOR canonicalisation (RFC 7049):
3333
--
3434
-- * Map keys are sorted lexicographically
3535
-- * Indefinite-length maps/lists are converted to finite-length maps/lists
3636
-- * The representation of the CBOR major types is as small as possible (provided by "cborg" package)
3737
--
38-
-- This function implements canonicalisation from CIP-29:
39-
-- https://github.com/cardano-foundation/CIPs/blob/master/CIP-0021/README.md#canonical-cbor-serialization-format
40-
-- See also: https://datatracker.ietf.org/doc/html/rfc7049#section-3.9
38+
-- This function implements only CBOR canonicalisation from CIP-21. Other requirements from CIP-21 are not implemented.
39+
--
40+
-- 1. CBOR RFC 7049, Canonicalisation description: https://datatracker.ietf.org/doc/html/rfc7049#section-3.9
41+
-- 2. CIP-21: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0021/README.md#canonical-cbor-serialization-format
4142
canonicaliseCborBs :: BS.ByteString -> Either DecoderError BS.ByteString
4243
canonicaliseCborBs originalCborBytes = serialiseToCBOR . canonicaliseTerm <$> deserialiseFromCBOR AsTerm originalCborBytes
4344

cardano-api/src/Cardano/Api/Internal/SerialiseLedgerCddl.hs

Lines changed: 37 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import Cardano.Api.Internal.SerialiseTextEnvelope
4646
, TextEnvelopeType (TextEnvelopeType)
4747
, deserialiseFromTextEnvelope
4848
, legacyComparison
49+
, serialiseTextEnvelope
4950
, serialiseToTextEnvelope
5051
)
5152
import Cardano.Api.Internal.Tx.Sign
@@ -57,13 +58,11 @@ import Cardano.Ledger.Binary qualified as CBOR
5758

5859
import Control.Monad.Trans.Except.Extra
5960
( firstExceptT
60-
, handleIOExceptT
6161
, hoistEither
6262
, newExceptT
6363
, runExceptT
6464
)
6565
import Data.Aeson qualified as Aeson
66-
import Data.Aeson.Encode.Pretty (Config (..), defConfig, encodePretty', keyOrder)
6766
import Data.Bifunctor (first)
6867
import Data.ByteString (ByteString)
6968
import Data.ByteString.Lazy qualified as LBS
@@ -136,11 +135,10 @@ writeByronTxFileTextEnvelopeCddl
136135
:: File content Out
137136
-> Byron.ATxAux ByteString
138137
-> IO (Either (FileError ()) ())
139-
writeByronTxFileTextEnvelopeCddl path w =
140-
runExceptT $ do
141-
handleIOExceptT (FileIOError (unFile path)) $ LBS.writeFile (unFile path) txJson
142-
where
143-
txJson = encodePretty' textEnvelopeCddlJSONConfig (serializeByronTx w) <> "\n"
138+
writeByronTxFileTextEnvelopeCddl path =
139+
writeLazyByteStringFile path
140+
. serialiseTextEnvelope
141+
. serializeByronTx
144142

145143
serializeByronTx :: Byron.ATxAux ByteString -> TextEnvelope
146144
serializeByronTx tx =
@@ -217,63 +215,51 @@ writeTxFileTextEnvelopeCddl
217215
-> File content Out
218216
-> Tx era
219217
-> IO (Either (FileError ()) ())
220-
writeTxFileTextEnvelopeCddl sbe = writeTxFileTextEnvelopeCddl' sbe False
218+
writeTxFileTextEnvelopeCddl sbe path =
219+
writeLazyByteStringFile path
220+
. serialiseTextEnvelope
221+
. serialiseTxToTextEnvelope sbe
221222

222-
-- | Write transaction in the text envelope format, the CBOR will be in canonical format according
223-
-- to CIP-21 https://github.com/cardano-foundation/CIPs/blob/master/CIP-0021/README.md#canonical-cbor-serialization-format
223+
-- | Write transaction in the text envelope format. The CBOR will be in canonical format according
224+
-- to RFC 7049. It is also a requirement of CIP-21, which is not fully implemented.
225+
--
226+
-- 1. RFC 7049: https://datatracker.ietf.org/doc/html/rfc7049#section-3.9
227+
-- 2. CIP-21: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0021/README.md#canonical-cbor-serialization-format
224228
writeTxFileTextEnvelopeCanonicalCddl
225229
:: ShelleyBasedEra era
226230
-> File content Out
227231
-> Tx era
228232
-> IO (Either (FileError ()) ())
229-
writeTxFileTextEnvelopeCanonicalCddl sbe = writeTxFileTextEnvelopeCddl' sbe True
230-
231-
writeTxFileTextEnvelopeCddl'
232-
:: ()
233-
=> ShelleyBasedEra era
234-
-> Bool
235-
-- ^ True to produce canonical CBOR
236-
-> File content Out
237-
-> Tx era
238-
-> IO (Either (FileError ()) ())
239-
writeTxFileTextEnvelopeCddl' era isCanonicalCbor path tx =
240-
runExceptT $ do
241-
handleIOExceptT (FileIOError (unFile path)) $ LBS.writeFile (unFile path) txJson
233+
writeTxFileTextEnvelopeCanonicalCddl sbe path =
234+
writeLazyByteStringFile path
235+
. serialiseTextEnvelope
236+
. canonicaliseTextEnvelopeCbor
237+
. serialiseTxToTextEnvelope sbe
242238
where
243-
txJson = encodePretty' textEnvelopeCddlJSONConfig (serialiseTxLedgerCddl era tx) <> "\n"
244-
245-
serialiseTxLedgerCddl :: ShelleyBasedEra era -> Tx era -> TextEnvelope
246-
serialiseTxLedgerCddl era' tx' =
247-
shelleyBasedEraConstraints era' $ do
248-
let te = serialiseToTextEnvelope (Just (TextEnvelopeDescr "Ledger Cddl Format")) tx'
249-
if isCanonicalCbor
250-
then do
251-
let canonicalisedTxBs =
252-
either
253-
(\err -> error $ "Impossible - deserialisation of just serialised bytes failed " <> show err)
254-
id
255-
. canonicaliseCborBs
256-
$ teRawCBOR te
257-
te{teRawCBOR = canonicalisedTxBs}
258-
else te
239+
canonicaliseTextEnvelopeCbor :: TextEnvelope -> TextEnvelope
240+
canonicaliseTextEnvelopeCbor te = do
241+
let canonicalisedTxBs =
242+
either
243+
(\err -> error $ "Impossible - deserialisation of just serialised bytes failed " <> show err)
244+
id
245+
. canonicaliseCborBs
246+
$ teRawCBOR te
247+
te{teRawCBOR = canonicalisedTxBs}
248+
249+
serialiseTxToTextEnvelope :: ShelleyBasedEra era -> Tx era -> TextEnvelope
250+
serialiseTxToTextEnvelope era' tx' =
251+
shelleyBasedEraConstraints era' $ do
252+
serialiseToTextEnvelope (Just "Ledger Cddl Format") tx'
259253

260254
writeTxWitnessFileTextEnvelopeCddl
261255
:: ShelleyBasedEra era
262256
-> File () Out
263257
-> KeyWitness era
264258
-> IO (Either (FileError ()) ())
265-
writeTxWitnessFileTextEnvelopeCddl sbe path w =
266-
runExceptT $ do
267-
handleIOExceptT (FileIOError (unFile path)) $ LBS.writeFile (unFile path) txJson
268-
where
269-
txJson = encodePretty' textEnvelopeCddlJSONConfig (serialiseWitnessLedgerCddl sbe w) <> "\n"
270-
271-
textEnvelopeCddlJSONConfig :: Config
272-
textEnvelopeCddlJSONConfig =
273-
defConfig{confCompare = textEnvelopeCddlJSONKeyOrder}
274-
275-
textEnvelopeCddlJSONKeyOrder :: Text -> Text -> Ordering
276-
textEnvelopeCddlJSONKeyOrder = keyOrder ["type", "description", "cborHex"]
259+
writeTxWitnessFileTextEnvelopeCddl sbe path =
260+
writeLazyByteStringFile path
261+
. serialiseTextEnvelope
262+
. serialiseWitnessLedgerCddl sbe
277263

278264
-- | This GADT allows us to deserialise a tx or key witness without
279265
-- having to provide the era.

cardano-api/src/Cardano/Api/Internal/SerialiseTextEnvelope.hs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ module Cardano.Api.Internal.SerialiseTextEnvelope
2525
, readTextEnvelopeFromFile
2626
, readTextEnvelopeOfTypeFromFile
2727
, textEnvelopeToJSON
28+
, serialiseTextEnvelope
2829
, legacyComparison
2930

3031
-- * Reading one of several key types
@@ -115,11 +116,11 @@ instance FromJSON TextEnvelope where
115116
parseJSONBase16 v =
116117
either fail return . Base16.decode . Text.encodeUtf8 =<< parseJSON v
117118

118-
textEnvelopeJSONConfig :: Config
119-
textEnvelopeJSONConfig = defConfig{confCompare = textEnvelopeJSONKeyOrder}
119+
textEnvelopeJsonConfig :: Config
120+
textEnvelopeJsonConfig = defConfig{confCompare = textEnvelopeJsonKeyOrder}
120121

121-
textEnvelopeJSONKeyOrder :: Text -> Text -> Ordering
122-
textEnvelopeJSONKeyOrder = keyOrder ["type", "description", "cborHex"]
122+
textEnvelopeJsonKeyOrder :: Text -> Text -> Ordering
123+
textEnvelopeJsonKeyOrder = keyOrder ["type", "description", "cborHex"]
123124

124125
textEnvelopeRawCBOR :: TextEnvelope -> ByteString
125126
textEnvelopeRawCBOR = teRawCBOR
@@ -254,7 +255,11 @@ writeFileTextEnvelope outputFile mbDescr a =
254255

255256
textEnvelopeToJSON :: HasTextEnvelope a => Maybe TextEnvelopeDescr -> a -> LBS.ByteString
256257
textEnvelopeToJSON mbDescr a =
257-
encodePretty' textEnvelopeJSONConfig (serialiseToTextEnvelope mbDescr a) <> "\n"
258+
serialiseTextEnvelope $ serialiseToTextEnvelope mbDescr a
259+
260+
-- | Serialise text envelope to pretty JSON
261+
serialiseTextEnvelope :: TextEnvelope -> LBS.ByteString
262+
serialiseTextEnvelope te = encodePretty' textEnvelopeJsonConfig te <> "\n"
258263

259264
readFileTextEnvelope
260265
:: HasTextEnvelope a

cardano-api/test/cardano-api-test/Test/Cardano/Api/CBOR.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ prop_roundtrip_GovernancePollAnswer_CBOR :: Property
348348
prop_roundtrip_GovernancePollAnswer_CBOR = property $ do
349349
H.trippingCbor AsGovernancePollAnswer =<< forAll genGovernancePollAnswer
350350

351-
-- | Test CBOR canonicalisation (according to CIP-21)
351+
-- | Test CBOR canonicalisation (according to RFC 7049, part of CIP-21)
352352
-- We're only testing ordering of the map keys and converting to finite collections here
353353
-- - the smallest representation is implemented in cborg library.
354354
prop_canonicalise_cbor :: Property

0 commit comments

Comments
 (0)