Skip to content
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

preserve Alonzo script integrity hash bug #2730

Merged
merged 1 commit into from
Apr 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions eras/alonzo/impl/src/Cardano/Ledger/Alonzo/PParams.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ import Cardano.Binary
)
import Cardano.Ledger.Alonzo.Language (Language (..))
import Cardano.Ledger.Alonzo.Scripts
( CostModels (..),
( CostModel,
CostModels (..),
ExUnits (..),
Prices (..),
getCostModelParams,
)
import Cardano.Ledger.BaseTypes
( NonNegativeInterval,
Expand Down Expand Up @@ -74,6 +76,7 @@ import Data.Coders
Wrapped (..),
decode,
encode,
encodeFoldableAsIndefinite,
field,
(!>),
(<!),
Expand Down Expand Up @@ -478,6 +481,15 @@ updatePParams pp ppup =
data LangDepView = LangDepView {tag :: ByteString, params :: ByteString}
deriving (Eq, Show, Ord, Generic, NoThunks)

-- In the Alonzo era, the map of languages to cost models was mistakenly encoded
-- using an indefinite CBOR map (contrary to canonical CBOR, as intended) when
-- computing the script integrity hash.
-- For this reason, PlutusV1 remains with this encoding.
-- Future versions of Plutus, starting with PlutusV2 in the Babbage era, will
-- use the intended definite length encoding.
legacyNonCanonicalCostModelEncoder :: CostModel -> Encoding
legacyNonCanonicalCostModelEncoder = encodeFoldableAsIndefinite . getCostModelParams

getLanguageView ::
forall era.
(HasField "_costmdls" (Core.PParams era) CostModels) =>
Expand All @@ -489,7 +501,7 @@ getLanguageView pp lang@PlutusV1 =
(serialize' (serialize' lang))
( serialize'
( serializeEncoding' $
maybe encodeNull toCBOR $
maybe encodeNull legacyNonCanonicalCostModelEncoder $
Map.lookup lang (unCostModels $ getField @"_costmdls" pp)
)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}

Expand All @@ -7,21 +8,35 @@
module Test.Cardano.Ledger.Alonzo.Golden
( goldenUTxOEntryMinAda,
goldenSerialization,
goldenScriptIntegrity,
)
where

import Cardano.Binary (serialize)
import Cardano.Ledger.Alonzo (AlonzoEra)
import Cardano.Ledger.Alonzo.Data (Data (..), hashData)
import Cardano.Ledger.Alonzo.Language (Language (..))
import Cardano.Ledger.Alonzo.PParams
( LangDepView (..),
PParams,
PParams' (..),
emptyPParams,
getLanguageView,
)
import Cardano.Ledger.Alonzo.Rules.Utxo (utxoEntrySize)
import Cardano.Ledger.Alonzo.Scripts (CostModels (..))
import Cardano.Ledger.Alonzo.TxBody (TxOut (..))
import Cardano.Ledger.BaseTypes (StrictMaybe (..))
import Cardano.Ledger.Coin (Coin (..))
import Cardano.Ledger.Mary.Value (Value (..), valueFromList)
import qualified Data.ByteString.Base16 as B16
import qualified Data.ByteString.Lazy as BSL
import Data.Char (chr)
import Data.Either (fromRight)
import qualified Data.Map.Strict as Map
import Plutus.V1.Ledger.Api (Data (..))
import Test.Cardano.Ledger.Alonzo.Examples.Consensus (ledgerExamplesAlonzo)
import Test.Cardano.Ledger.Alonzo.PlutusScripts (testingCostModelV1, testingCostModelV2)
import Test.Cardano.Ledger.EraBuffet (StandardCrypto)
import Test.Cardano.Ledger.Mary.Golden
( largestName,
Expand Down Expand Up @@ -174,3 +189,72 @@ goldenSerialization =
expected <- (BSL.readFile "golden/tx.cbor")
serialize (SLE.sleTx ledgerExamplesAlonzo) @?= expected
]

exPP :: PParams (AlonzoEra StandardCrypto)
exPP =
emptyPParams
{ _costmdls =
CostModels $
Map.fromList [(PlutusV1, testingCostModelV1), (PlutusV2, testingCostModelV2)]
}

exampleLangDepViewPV1 :: LangDepView
exampleLangDepViewPV1 = LangDepView b1 b2
where
b1 =
fromRight (error "invalid hex encoding of the language inside exampleLangDepViewPV1") $
B16.decode "4100"
b2 =
fromRight (error "invalid hex encoding of the cost model inside exampleLangDepViewPV1") $
B16.decode $
"5901d59f1a000302590001011a00060bc719026d00011a000249f01903e80001"
<> "1a000249f018201a0025cea81971f70419744d186419744d186419744d186419"
<> "744d186419744d186419744d18641864186419744d18641a000249f018201a00"
<> "0249f018201a000249f018201a000249f01903e800011a000249f018201a0002"
<> "49f01903e800081a000242201a00067e2318760001011a000249f01903e80008"
<> "1a000249f01a0001b79818f7011a000249f0192710011a0002155e19052e0119"
<> "03e81a000249f01903e8011a000249f018201a000249f018201a000249f01820"
<> "01011a000249f0011a000249f0041a000194af18f8011a000194af18f8011a00"
<> "02377c190556011a0002bdea1901f1011a000249f018201a000249f018201a00"
<> "0249f018201a000249f018201a000249f018201a000249f018201a000242201a"
<> "00067e23187600010119f04c192bd200011a000249f018201a000242201a0006"
<> "7e2318760001011a000242201a00067e2318760001011a0025cea81971f70400"
<> "1a000141bb041a000249f019138800011a000249f018201a000302590001011a"
<> "000249f018201a000249f018201a000249f018201a000249f018201a000249f0"
<> "18201a000249f018201a000249f018201a00330da70101ff"

exampleLangDepViewPV2 :: LangDepView
exampleLangDepViewPV2 = LangDepView b1 b2
where
b1 =
fromRight (error "invalid hex encoding of the language inside exampleLangDepViewPV2") $
B16.decode "01"
b2 =
fromRight (error "invalid hex encoding of the cost model inside exampleLangDepViewPV2") $
B16.decode $
"98a61a000302590001011a00060bc719026d00011a000249f01903e800011a00"
<> "0249f018201a0025cea81971f70419744d186419744d186419744d186419744d"
<> "186419744d186419744d18641864186419744d18641a000249f018201a000249"
<> "f018201a000249f018201a000249f01903e800011a000249f018201a000249f0"
<> "1903e800081a000242201a00067e2318760001011a000249f01903e800081a00"
<> "0249f01a0001b79818f7011a000249f0192710011a0002155e19052e011903e8"
<> "1a000249f01903e8011a000249f018201a000249f018201a000249f018200101"
<> "1a000249f0011a000249f0041a000194af18f8011a000194af18f8011a000237"
<> "7c190556011a0002bdea1901f1011a000249f018201a000249f018201a000249"
<> "f018201a000249f018201a000249f018201a000249f018201a000242201a0006"
<> "7e23187600010119f04c192bd200011a000249f018201a000242201a00067e23"
<> "18760001011a000242201a00067e2318760001011a0025cea81971f704001a00"
<> "0141bb041a000249f019138800011a000249f018201a000302590001011a0002"
<> "49f018201a000249f018201a000249f018201a000249f018201a000249f01820"
<> "1a000249f018201a000249f018201a00330da70101"

testScriptIntegritpHash :: PParams (AlonzoEra StandardCrypto) -> Language -> LangDepView -> IO ()
testScriptIntegritpHash pp lang view = getLanguageView pp lang @?= view

goldenScriptIntegrity :: TestTree
goldenScriptIntegrity =
testGroup
"golden tests - script integrity hash"
[ testCase "PlutusV1" $ testScriptIntegritpHash exPP PlutusV1 exampleLangDepViewPV1,
testCase "PlutusV2" $ testScriptIntegritpHash exPP PlutusV2 exampleLangDepViewPV2
]
2 changes: 2 additions & 0 deletions eras/alonzo/test-suite/test/Tests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ mainTests =
CDDL.tests 5,
Golden.goldenUTxOEntryMinAda,
Golden.goldenSerialization,
Golden.goldenScriptIntegrity,
plutusScriptExamples,
txInfoTests
]
Expand All @@ -51,6 +52,7 @@ fastTests =
CDDL.tests 1,
Golden.goldenUTxOEntryMinAda,
Golden.goldenSerialization,
Golden.goldenScriptIntegrity,
plutusScriptExamples,
txInfoTests
]
Expand Down