From e75a0ce3d8142891353c6897fd820131ae1cb76a Mon Sep 17 00:00:00 2001 From: Konstantinos Lambrou-Latreille Date: Mon, 26 Jan 2026 11:18:50 -0500 Subject: [PATCH] Add golden test for hash computation of serialised CBOR script read from file (either binary or text file) --- cardano-api/cardano-api.cabal | 1 + .../Test/Golden/Cardano/Api/Script.hs | 62 +++++++++++++++++- .../Script/PlutusScriptV1/alwayssucceeds.bin | Bin 0 -> 8 bytes .../Script/PlutusScriptV1/alwayssucceeds.txt | 1 + 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 cardano-api/test/cardano-api-golden/files/Script/PlutusScriptV1/alwayssucceeds.bin create mode 100644 cardano-api/test/cardano-api-golden/files/Script/PlutusScriptV1/alwayssucceeds.txt diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index 17bb6c39ca..fa04e863ec 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -443,6 +443,7 @@ test-suite cardano-api-golden cardano-ledger-shelley, cardano-protocol-tpraos, containers, + directory, errors, filepath, hedgehog >=1.1, diff --git a/cardano-api/test/cardano-api-golden/Test/Golden/Cardano/Api/Script.hs b/cardano-api/test/cardano-api-golden/Test/Golden/Cardano/Api/Script.hs index dd6db34471..cdc8afbd12 100644 --- a/cardano-api/test/cardano-api-golden/Test/Golden/Cardano/Api/Script.hs +++ b/cardano-api/test/cardano-api-golden/Test/Golden/Cardano/Api/Script.hs @@ -8,6 +8,7 @@ module Test.Golden.Cardano.Api.Script , test_golden_SimpleScriptV2_All , test_golden_SimpleScriptV2_Any , test_golden_SimpleScriptV2_MofN + , test_golden_AlwaysSucceeds , test_roundtrip_SimpleScript_JSON , test_roundtrip_ScriptData , test_roundtrip_HashableScriptData_JSON @@ -20,15 +21,21 @@ import Cardano.Api.Parser.Text qualified as P import Cardano.Ledger.Api.Era qualified as L import Data.Aeson -import GHC.Stack -import System.FilePath (()) +import Data.ByteString qualified as BS +import Data.ByteString.Char8 qualified as BS +import Data.Text qualified as Text +import GHC.Stack (HasCallStack) +import System.Directory (createDirectoryIfMissing) +import System.Environment (lookupEnv) +import System.FilePath (takeDirectory, ()) import Test.Gen.Cardano.Api.Typed import Hedgehog ((===)) import Hedgehog qualified as H +import Hedgehog.Extras qualified as H import Hedgehog.Extras.Aeson -import Test.Tasty (TestTree) +import Test.Tasty (TestTree, testGroup) import Test.Tasty.Hedgehog (testProperty) exampleSimpleScriptV1_All :: SimpleScript @@ -121,6 +128,55 @@ test_golden_SimpleScriptV2_MofN = testProperty "golden SimpleScriptV2 MofN" $ goldenTestJsonValuePretty exampleSimpleScriptV2_MofN (goldenPath "SimpleV2/atleast.script") +-- | Test showing that we can correctly deserialise a Plutus script that was +-- saved in a CBOR hex-encoded text file or in a CBOR binary file +test_golden_AlwaysSucceeds :: TestTree +test_golden_AlwaysSucceeds = do + let expectedScriptHash = "58503a1d89a21fc9fc53d6a7cccef47341175a8f47636f57ccbdca2d" + + testGroup + "golden AlwaysSucceeds" + [ testProperty "golden AlwaysSucceeds PlutusScriptV1 hex-encoded CBOR" $ do + let goldenFile = goldenPath "PlutusScriptV1/alwayssucceeds.txt" + H.propertyOnce $ do + H.diffVsGoldenFile + (Text.unpack $ serialiseToRawBytesHexText $ examplePlutusScriptAlwaysSucceeds WitCtxTxIn) + goldenFile + + cborBytes <- H.evalIO $ BS.readFile goldenFile + -- 'BS.strip' is necessary in some scenarios such as when some user opens + -- the files and adds a newline (often done automically by their text + -- editor) + script <- H.evalEither $ deserialiseFromRawBytesHex $ BS.strip cborBytes + + expectedScriptHash === serialiseToRawBytesHexText (hashScript (PlutusScript PlutusScriptV1 script)) + , testProperty "golden AlwaysSucceeds PlutusScriptV1 bytestring CBOR" $ + H.propertyOnce $ do + let goldenFile = goldenPath "PlutusScriptV1/alwayssucceeds.bin" + cborBytes = serialiseToCBOR $ examplePlutusScriptAlwaysSucceeds WitCtxTxIn + + -- Write raw CBOR bytes if RECREATE_GOLDEN_FILES is set + -- Not using diffVsGoldenFile because we want to save the 'ByteString', and + -- not have to convert it to 'Text'. + -- Ideally, we should have a `diffVsGoldenBinaryFile + recreate <- H.evalIO $ lookupEnv "RECREATE_GOLDEN_FILES" + case recreate of + Just _ -> H.evalIO $ do + createDirectoryIfMissing True (takeDirectory goldenFile) + BS.writeFile goldenFile cborBytes + Nothing -> pure () + + -- Read back raw CBOR and deserialize + cborBytesRead <- H.evalIO $ BS.readFile goldenFile + -- 'BS.strip' is necessary in some scenarios such as when some user opens + -- the files and adds a newline (often done automically by their text + -- editor) + script <- + H.evalEither $ deserialiseFromCBOR (AsPlutusScript AsPlutusScriptV1) $ BS.strip cborBytesRead + + expectedScriptHash === serialiseToRawBytesHexText (hashScript (PlutusScript PlutusScriptV1 script)) + ] + test_roundtrip_SimpleScript_JSON :: TestTree test_roundtrip_SimpleScript_JSON = testProperty "roundtrip SimpleScript JSON" . H.property $ do diff --git a/cardano-api/test/cardano-api-golden/files/Script/PlutusScriptV1/alwayssucceeds.bin b/cardano-api/test/cardano-api-golden/files/Script/PlutusScriptV1/alwayssucceeds.bin new file mode 100644 index 0000000000000000000000000000000000000000..44d05671bbb0e98ef09a42aecd5a7924984818e8 GIT binary patch literal 8 PcmZ=~WMEKIVh{uX14aOz literal 0 HcmV?d00001 diff --git a/cardano-api/test/cardano-api-golden/files/Script/PlutusScriptV1/alwayssucceeds.txt b/cardano-api/test/cardano-api-golden/files/Script/PlutusScriptV1/alwayssucceeds.txt new file mode 100644 index 0000000000..61464f0742 --- /dev/null +++ b/cardano-api/test/cardano-api-golden/files/Script/PlutusScriptV1/alwayssucceeds.txt @@ -0,0 +1 @@ +4701000022220011 \ No newline at end of file