-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test that consensus emits valid CBOR #323
Test that consensus emits valid CBOR #323
Conversation
bs = toLazyByteString enc_a | ||
|
||
validFlatTerm (toFlatTerm enc_a) ?! "Encoded flat term is not valid: " <> show enc_a | ||
(bsRem, a' ) <- deserialiseFromBytes dec bs `onError` showByteString bs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to use fromFlatTerm instead of going through bytestrings? Or maybe do both to be extra sure we are catching all bugs?
encodersProduceValidCBOR :: | ||
forall blk . (SerialiseDiskConstraints blk) | ||
=> CodecConfig blk | ||
-> Examples blk | ||
-> TestTree |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this function could go into the consensus testlib
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, then it could also be re-used in Test.Consensus.{Byron,Shelley}.Serialisation
👍
import Test.Util.Serialisation.Roundtrip | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant newline
-> TestTree | ||
encodersProduceValidCBOR codecConfig examples = | ||
testGroup "Encoders produce valid CBOR" $ | ||
[ test exampleBlock "Block" (encodeDisk codecConfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if something like testProperty "Block" $ roundtrip (encodeDisk codecConfig) (decodeDisk codecConfig) exampleBlock
could also work, since it removes a bit of duplication
@@ -78,31 +81,53 @@ roundtrip enc dec = roundtrip' enc (const <$> dec) | |||
|
|||
-- | Roundtrip property for values annotated with their serialized form | |||
-- | |||
-- In addition, we check that the encoded CBOR is valid using [validFlatTerm](https://hackage.haskell.org/package/cborg-0.2.9.0/docs/Codec-CBOR-FlatTerm.html#v:validFlatTerm). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Haddock markup:
-- In addition, we check that the encoded CBOR is valid using [validFlatTerm](https://hackage.haskell.org/package/cborg-0.2.9.0/docs/Codec-CBOR-FlatTerm.html#v:validFlatTerm). | |
-- In addition, we check that the encoded CBOR is valid using 'validFlatTerm'. |
d600ae3
to
d1048b0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I only have some minor comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be sure: nothing changed when moving these definitions from the Golden
module to this module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, I just extracted the relevant bits and pieces.
@@ -28,6 +28,7 @@ import Test.ThreadNet.Util.SimpleBlock | |||
import Test.Util.HardFork.Future (singleEraFuture) | |||
import Test.Util.Orphans.Arbitrary () | |||
import Test.Util.Serialisation.Roundtrip | |||
import Test.Util.Serialisation.SomeResult () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm slightly surprised this is necessary, since the SomeResult
module contains no orphan instances. What happens if you remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
@@ -28,30 +28,38 @@ module Test.Util.Serialisation.Roundtrip ( | |||
, roundtrip_SerialiseNodeToNode | |||
, roundtrip_all | |||
, roundtrip_envelopes | |||
-- * Unit tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-- * Unit tests | |
-- * Roundtrip tests for examples |
examplesRoundtrip :: | ||
forall blk . (SerialiseDiskConstraints blk, Eq blk, Show blk, LedgerSupportsProtocol blk) | ||
=> CodecConfig blk | ||
-> Examples blk | ||
-> [TestTree] | ||
examplesRoundtrip codecConfig examples = | ||
[ testRoundtripFor "Block" (encodeDisk codecConfig) (decodeDisk codecConfig) exampleBlock | ||
, testRoundtripFor "Header hash" encode (const <$> decode) exampleHeaderHash | ||
, testRoundtripFor "Ledger state" (encodeDisk codecConfig) (const <$> decodeDisk codecConfig) exampleLedgerState | ||
, testRoundtripFor "Annotated tip" (encodeDisk codecConfig) (const <$> decodeDisk codecConfig) exampleAnnTip | ||
, testRoundtripFor "Chain dependent state" (encodeDisk codecConfig) (const <$> decodeDisk codecConfig) exampleChainDepState | ||
, testRoundtripFor "Extended ledger state" encodeExt (const <$> decodeExt) exampleExtLedgerState | ||
] | ||
where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The body before the where
should probably have an additional two-space indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed that. Thanks!
examplesRoundtrip :: | ||
forall blk . (SerialiseDiskConstraints blk, Eq blk, Show blk, LedgerSupportsProtocol blk) | ||
=> CodecConfig blk | ||
-> Examples blk | ||
-> [TestTree] | ||
examplesRoundtrip codecConfig examples = | ||
[ testRoundtripFor "Block" (encodeDisk codecConfig) (decodeDisk codecConfig) exampleBlock | ||
, testRoundtripFor "Header hash" encode (const <$> decode) exampleHeaderHash | ||
, testRoundtripFor "Ledger state" (encodeDisk codecConfig) (const <$> decodeDisk codecConfig) exampleLedgerState | ||
, testRoundtripFor "Annotated tip" (encodeDisk codecConfig) (const <$> decodeDisk codecConfig) exampleAnnTip | ||
, testRoundtripFor "Chain dependent state" (encodeDisk codecConfig) (const <$> decodeDisk codecConfig) exampleChainDepState | ||
, testRoundtripFor "Extended ledger state" encodeExt (const <$> decodeExt) exampleExtLedgerState | ||
] | ||
where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can trade in some horizontal real estate for vertical real estate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried putting the type in one line but I think it's too long. However, I corrected the indentation in testRoundtripFor
.
validFlatTerm (toFlatTerm enc_a) ?! "Encoded flat term is not valid: " <> show enc_a | ||
(bsRem, a' ) <- deserialiseFromBytes dec bs `onError` showByteString bs | ||
validFlatTerm flatTerm_a ?! "Encoded flat term is not valid: " <> show enc_a | ||
-- TODO: requires https://github.com/well-typed/cborg/pull/325 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be reflected in an issue, such that we don't forget about completing this TODO once a new version of cborg
is released?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a s-r-p that contains the cborg
fix. I can remove this comment.
[ testGroup "Shelley examples roundtrip" $ examplesRoundtrip ShelleyCodecConfig Shelley.Examples.examplesShelley | ||
, testGroup "Mary examples roundtrip" $ examplesRoundtrip ShelleyCodecConfig Shelley.Examples.examplesMary | ||
, testGroup "Allegra examples roundtrip" $ examplesRoundtrip ShelleyCodecConfig Shelley.Examples.examplesAllegra | ||
, testGroup "Alonzo examples roundtrip" $ examplesRoundtrip ShelleyCodecConfig Shelley.Examples.examplesAlonzo | ||
, testGroup "Babbage examples roundtrip" $ examplesRoundtrip ShelleyCodecConfig Shelley.Examples.examplesBabbage | ||
, testGroup "Conway examples roundtrip" $ examplesRoundtrip ShelleyCodecConfig Shelley.Examples.examplesConway |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Random idea I had: maybe we should store Shelley-based era examples in an NP Examples ShelleyEras
and map the roundtrip test function over it. That way, we won't forget about adding a roundtrip test when we add a new shelley-based era
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's an excellent idea! Thanks. Let me try and see what I can do.
This required to factor out 'SomeResult' as well.
2fcfa97
to
7923927
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@@ -124,16 +127,20 @@ roundtrip' enc dec a = checkRoundtripResult $ do | |||
flatTerm_a = toFlatTerm enc_a | |||
|
|||
validFlatTerm flatTerm_a ?! "Encoded flat term is not valid: " <> show enc_a | |||
a' <- fromFlatTerm dec flatTerm_a | |||
a == a' bs ?! show a <> " /= " <> show (a' bs) | |||
-- TODO: the decode test via FlatTerm will currently fail because https://github.com/input-output-hk/cardano-ledger/issues/3741 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the issue link back to this part of the code, such that we don't forget re-enabling it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I'll have to add a permalink after merging this one
Function `Test.Util.Serialisation.Roundtrip.roundtrip'` has been adapted to check that the resulting encoding is valid according to [validFlatTerm](https://hackage.haskell.org/package/cborg-0.2.9.0/docs/Codec-CBOR-FlatTerm.html#v:validFlatTerm). We also test that the CBOR encoders for Cardano examples are valid by testing them with the `roundtrip'` function.
7923927
to
f8426b2
Compare
This reverts commit f8426b2 from #323. These tests turned out to be flaky, see eg [here](https://github.com/input-output-hk/ouroboros-consensus/actions/runs/6252676869/job/16976447179?pr=354#step:15:1589).
Needs: well-typed/cborg#324.
Closes IntersectMBO/ouroboros-network#3099.