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

Add golden tests to ProtocolParameters serialization #457

Merged
merged 30 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
60e21a7
Create golden tests for ProtocolParameters
palas Feb 16, 2024
cedc88d
Update to revised version of cardano-ledger branch
palas Feb 28, 2024
1ee7a48
Update to latest revision and patch JSON in tests
palas Feb 29, 2024
c695dde
Remove unused pragma
palas Mar 15, 2024
2c65246
Fix module declaration layout
palas Mar 15, 2024
aaac996
Rename examplePP to legacyCardanoApiProtocolParameters
palas Mar 15, 2024
6ea8472
Use NumericUnderscores for numbers over 9999
palas Mar 15, 2024
5c2293a
Rename `ProtocolParameters` to `LegacyProtocolParameters` to indicate…
palas Mar 15, 2024
b075d87
Fix module declaration layout
palas Mar 15, 2024
41fcb87
Fix test comments to be more explicative
palas Mar 15, 2024
af202ad
Rename serializedProtocolParams to serializedProtocolParameters to be…
palas Mar 15, 2024
8634917
Add Haddock to ValidatedSerializedPair data structure
palas Mar 15, 2024
175010d
Improve comment in `ppParamsRoundtrip`
palas Mar 15, 2024
558f182
Add explanatory comment fo `filtersForEra` function
palas Mar 15, 2024
bbb271d
Fix issue from rebasing
palas Mar 15, 2024
10f511e
Use `Proxy` instead of `undefined`
palas Mar 18, 2024
4be3c4e
Add extension to extensionless JSONs
palas Mar 18, 2024
7078622
Remove unnecessary '|' from Haddock comments
palas Mar 18, 2024
70387a0
Remove source stanzas
palas Apr 10, 2024
4ac07fa
Update tests
palas Apr 10, 2024
9dac970
Add comment explaining reason for patch
palas Apr 15, 2024
e77a254
Use `void . leftFail` instead of pattern matching
palas Apr 15, 2024
371b0c8
Rename function `replace` to `renameKey` and addd comment
palas Apr 15, 2024
78a136a
Rename `goldenProtocolParametersToPParams` to `goldenLegacyProtocolPa…
palas Apr 15, 2024
482ea8c
Improve error message for `goldenLegacyProtocolParametersToPParams`
palas Apr 15, 2024
269e03d
Improve error messages for `patchProtocolParamsJSONOrFail` and add co…
palas Apr 15, 2024
3cb2160
Add `PlutusV1` parameters to legacy golden test
palas Apr 15, 2024
69702c7
Move `do` in `genValidSerializedPair` to a local variable
palas Apr 15, 2024
d8ceb93
Explain motivation for tests and why we don't test Conway
palas Apr 15, 2024
527f16c
Rename `ppParamsRoundtrip` and improve its comment
palas Apr 15, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/haskell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:

env:
# Modify this value to "invalidate" the cabal cache.
CABAL_CACHE_VERSION: "2024-02-15"
CABAL_CACHE_VERSION: "2024-02-29-golden"
# these two are msys2 env vars, they have no effect on non-msys2 installs.
MSYS2_PATH_TYPE: inherit
MSYSTEM: MINGW64
Expand Down
4 changes: 4 additions & 0 deletions cardano-api/cardano-api.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ test-suite cardano-api-test
Test.Cardano.Api.KeysByron
Test.Cardano.Api.Ledger
Test.Cardano.Api.Metadata
Test.Cardano.Api.ProtocolParameters
Test.Cardano.Api.Typed.Address
Test.Cardano.Api.Typed.Bech32
Test.Cardano.Api.Typed.CBOR
Expand All @@ -358,11 +359,13 @@ test-suite cardano-api-golden
, bytestring
, cardano-api
, cardano-api:gen
, cardano-api:internal
, cardano-binary
, cardano-crypto-class ^>= 2.1.2
, cardano-data >= 1.0
, cardano-ledger-alonzo
, cardano-ledger-api ^>= 1.9
, cardano-ledger-babbage >= 1.6.0
, cardano-ledger-core:{cardano-ledger-core, testlib} >= 1.8
, cardano-ledger-shelley
, cardano-ledger-shelley-test >= 1.2.0.1
Expand All @@ -389,4 +392,5 @@ test-suite cardano-api-golden
, Test.Golden.Cardano.Api.Ledger
, Test.Golden.Cardano.Api.Typed.Script
, Test.Golden.Cardano.Api.Value
, Test.Golden.Cardano.Api.ProtocolParameters
, Test.Golden.ErrorsSpec
33 changes: 15 additions & 18 deletions cardano-api/internal/Cardano/Api/ProtocolParameters.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1632,22 +1632,9 @@ toAlonzoPParams
protocolParamDecentralization
} = do
ppAlonzoCommon <- toAlonzoCommonPParams protocolParameters
-- QUESTION? This is strange, why do we need to construct Alonzo Tx with Babbage PParams?
-- This feels to me like an issue with the api design, as there should never be such an
-- inconsistency, because PParams affect the validity of the transaction.
d <- case protocolParamDecentralization of
-- The decentralization parameter is deprecated in Babbage
-- so we default to 0 if no decentralization parameter is found
-- in the api's 'ProtocolParameter' type. If we don't do this
-- we won't be able to construct an Alonzo tx using the Babbage
-- era's protocol parameter because our only other option is to
-- error.
Nothing -> Right minBound
Just dParam -> boundRationalEither "D" dParam
-- This is the correct implementation that should be the used instead:
-- d <- requireParam "protocolParamDecentralization"
-- (boundRationalEither "D")
-- protocolParamDecentralization
d <- requireParam "protocolParamDecentralization"
(boundRationalEither "D")
protocolParamDecentralization
let ppAlonzo =
ppAlonzoCommon
& ppDL .~ d
Expand Down Expand Up @@ -1685,7 +1672,7 @@ fromLedgerPParams
fromLedgerPParams ShelleyBasedEraShelley = fromShelleyPParams
fromLedgerPParams ShelleyBasedEraAllegra = fromShelleyPParams
fromLedgerPParams ShelleyBasedEraMary = fromShelleyPParams
fromLedgerPParams ShelleyBasedEraAlonzo = fromAlonzoPParams
fromLedgerPParams ShelleyBasedEraAlonzo = fromExactlyAlonzoPParams
fromLedgerPParams ShelleyBasedEraBabbage = fromBabbagePParams
fromLedgerPParams ShelleyBasedEraConway = fromConwayPParams

Expand Down Expand Up @@ -1743,6 +1730,7 @@ fromAlonzoPParams :: AlonzoEraPParams ledgerera
fromAlonzoPParams pp =
(fromShelleyCommonPParams pp) {
protocolParamCostModels = fromAlonzoCostModels $ pp ^. ppCostModelsL
, protocolParamDecentralization = Just . Ledger.unboundRational $ pp ^. ppDG
, protocolParamPrices = Just . fromAlonzoPrices $ pp ^. ppPricesL
, protocolParamMaxTxExUnits = Just . fromAlonzoExUnits $ pp ^. ppMaxTxExUnitsL
, protocolParamMaxBlockExUnits = Just . fromAlonzoExUnits $ pp ^. ppMaxBlockExUnitsL
Expand All @@ -1751,13 +1739,22 @@ fromAlonzoPParams pp =
, protocolParamMaxCollateralInputs = Just $ pp ^. ppMaxCollateralInputsL
}

fromExactlyAlonzoPParams :: (AlonzoEraPParams ledgerera, Ledger.ExactEra Ledger.AlonzoEra ledgerera)
=> PParams ledgerera
-> ProtocolParameters
fromExactlyAlonzoPParams pp =
(fromAlonzoPParams pp) {
protocolParamUTxOCostPerByte = Just . unCoinPerWord $ pp ^. ppCoinsPerUTxOWordL
}

fromBabbagePParams :: BabbageEraPParams ledgerera
=> PParams ledgerera
-> ProtocolParameters
fromBabbagePParams pp =
(fromAlonzoPParams pp)
{ protocolParamUTxOCostPerByte = Just . unCoinPerByte $ pp ^. ppCoinsPerUTxOByteL
}
, protocolParamDecentralization = Nothing
}

fromConwayPParams :: BabbageEraPParams ledgerera
=> PParams ledgerera
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ import Test.Tasty.Hedgehog (testProperty)

test_golden_ShelleyGenesis :: TestTree
test_golden_ShelleyGenesis = testProperty "golden ShelleyGenesis" $
H.goldenTestJsonValuePretty exampleShelleyGenesis "test/cardano-api-golden/files/golden/ShelleyGenesis"
H.goldenTestJsonValuePretty exampleShelleyGenesis "test/cardano-api-golden/files/golden/ShelleyGenesis.json"
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Test.Golden.Cardano.Api.ProtocolParameters
( test_golden_ProtocolParameters
, test_golden_ProtocolParameters_to_PParams
) where

import Cardano.Api (AnyPlutusScriptVersion (AnyPlutusScriptVersion), CostModel (..),
ExecutionUnits (..), PlutusScriptVersion (..), makePraosNonce)
import Cardano.Api.Ledger (Coin (..), EpochInterval (EpochInterval), StandardCrypto)
import Cardano.Api.ProtocolParameters (ExecutionUnitPrices (..), ProtocolParameters (..))

import Cardano.Ledger.Alonzo (AlonzoEra)
import Cardano.Ledger.Alonzo.PParams (AlonzoPParams (..))
import Cardano.Ledger.Babbage (BabbageEra)
import Cardano.Ledger.Babbage.PParams (BabbagePParams (..))
import Cardano.Ledger.Plutus.CostModels (costModelParamsCount)
import Cardano.Ledger.Plutus.Language (Language (..))
import Cardano.Ledger.Shelley (ShelleyEra)
import Cardano.Ledger.Shelley.PParams (ShelleyPParams (..))

import Data.Aeson (FromJSON, eitherDecode, encode)
import Data.ByteString.Lazy (ByteString)
import Data.Functor.Identity (Identity)
import Data.Map (Map)
import qualified Data.Map as M
import Data.Proxy (Proxy (..))

import Hedgehog (Property, property, success)
import qualified Hedgehog.Extras.Aeson as H
import Hedgehog.Internal.Property (failWith)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.Hedgehog (testProperty)

test_golden_ProtocolParameters :: TestTree
test_golden_ProtocolParameters = testProperty "golden ProtocolParameters" $ do
H.goldenTestJsonValuePretty legacyCardanoApiProtocolParameters "test/cardano-api-golden/files/golden/LegacyProtocolParameters.json"

test_golden_ProtocolParameters_to_PParams :: TestTree
test_golden_ProtocolParameters_to_PParams =
testGroup "golden ProtocolParameter tests"
[ testProperty "ShelleyPParams" $
goldenLegacyProtocolParametersToPParams (Proxy :: Proxy (ShelleyPParams Identity (ShelleyEra StandardCrypto)))
, testProperty "AlonzoPParams" $
goldenLegacyProtocolParametersToPParams (Proxy :: Proxy (AlonzoPParams Identity (AlonzoEra StandardCrypto)))
, testProperty "BabbagePParams" $
goldenLegacyProtocolParametersToPParams (Proxy :: Proxy (BabbagePParams Identity (BabbageEra StandardCrypto)))
]

-- Test that tries decoding the legacy protocol parameters golden file
-- 'legacyCardanoApiProtocolParameters' as the type provided as a 'Proxy'.
goldenLegacyProtocolParametersToPParams :: forall pp. FromJSON pp => Proxy pp -> Property
goldenLegacyProtocolParametersToPParams proxy =
property $ case decodedLegacyCardanoApiProtocolParameters of
Left err -> failWith Nothing
("goldenLegacyProtocolParametersToPParams could not decode golden file as "
<> show proxy
<> ": "
<> show err)
Right _ -> success
where
bytestringLegacyCardanoApiProtocolParameters :: ByteString
bytestringLegacyCardanoApiProtocolParameters = encode legacyCardanoApiProtocolParameters

decodedLegacyCardanoApiProtocolParameters :: Either String pp
decodedLegacyCardanoApiProtocolParameters = eitherDecode bytestringLegacyCardanoApiProtocolParameters

legacyCardanoApiProtocolParameters :: ProtocolParameters
legacyCardanoApiProtocolParameters = ProtocolParameters { protocolParamUTxOCostPerByte = Just $ Coin 1_000_000
, protocolParamTxFeePerByte = Coin 2_000_000
, protocolParamTxFeeFixed = Coin 1_500_000
, protocolParamTreasuryCut = 0.1
, protocolParamStakePoolTargetNum = 100
, protocolParamStakePoolDeposit = Coin 1_000_000_000
, protocolParamStakeAddressDeposit = Coin 10_000_000
, protocolParamProtocolVersion = (2, 3)
, protocolParamPrices = Just executionUnitPrices
, protocolParamPoolRetireMaxEpoch = Cardano.Api.Ledger.EpochInterval 4
, protocolParamPoolPledgeInfluence = 0.54
, protocolParamMonetaryExpansion = 0.23
, protocolParamMinUTxOValue = Just $ Coin 3_000_000
, protocolParamMinPoolCost = Coin 3_500_000
, protocolParamMaxValueSize = Just 10
, protocolParamMaxTxSize = 3000
, protocolParamMaxTxExUnits = Just executionUnits
, protocolParamMaxCollateralInputs = Just 10
, protocolParamMaxBlockHeaderSize = 1200
, protocolParamMaxBlockExUnits = Just executionUnits2
, protocolParamMaxBlockBodySize = 5000
, protocolParamExtraPraosEntropy = Just $ makePraosNonce "entropyEntropy"
, protocolParamDecentralization = Just 0.52
, protocolParamCostModels = costModels
, protocolParamCollateralPercent = Just 23
}
where
executionUnitPrices :: ExecutionUnitPrices
executionUnitPrices = ExecutionUnitPrices { priceExecutionSteps = 0.3
, priceExecutionMemory = 0.2
}

costModels :: Map AnyPlutusScriptVersion CostModel
costModels = M.fromList [ (AnyPlutusScriptVersion PlutusScriptV3, CostModel [1..numParams PlutusV3])
, (AnyPlutusScriptVersion PlutusScriptV2, CostModel [1..numParams PlutusV2])
, (AnyPlutusScriptVersion PlutusScriptV1, CostModel [1..numParams PlutusV1])
]

numParams :: Language -> Integer
numParams = fromIntegral . costModelParamsCount

executionUnits :: ExecutionUnits
executionUnits = ExecutionUnits { executionSteps = 4300
, executionMemory = 2300
}

executionUnits2 :: ExecutionUnits
executionUnits2 = ExecutionUnits { executionSteps = 5600
, executionMemory = 3400
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,32 +92,32 @@ goldenPath = "test/cardano-api-golden/files/golden/Script"
test_golden_SimpleScriptV1_All :: TestTree
test_golden_SimpleScriptV1_All =
testProperty "golden SimpleScriptV1 All" $
goldenTestJsonValuePretty exampleSimpleScriptV1_All (goldenPath </> "SimpleV1/all")
goldenTestJsonValuePretty exampleSimpleScriptV1_All (goldenPath </> "SimpleV1/all.script")

test_golden_SimpleScriptV1_Any :: TestTree
test_golden_SimpleScriptV1_Any =
testProperty "golden SimpleScriptV1 Any" $
goldenTestJsonValuePretty exampleSimpleScriptV1_Any (goldenPath </> "SimpleV1/any")
goldenTestJsonValuePretty exampleSimpleScriptV1_Any (goldenPath </> "SimpleV1/any.script")

test_golden_SimpleScriptV1_MofN :: TestTree
test_golden_SimpleScriptV1_MofN =
testProperty "golden SimpleScriptV1 MofN" $
goldenTestJsonValuePretty exampleSimpleScriptV1_MofN (goldenPath </> "SimpleV1/atleast")
goldenTestJsonValuePretty exampleSimpleScriptV1_MofN (goldenPath </> "SimpleV1/atleast.script")

test_golden_SimpleScriptV2_All :: TestTree
test_golden_SimpleScriptV2_All =
testProperty "golden SimpleScriptV2 All" $
goldenTestJsonValuePretty exampleSimpleScriptV2_All (goldenPath </> "SimpleV2/all")
goldenTestJsonValuePretty exampleSimpleScriptV2_All (goldenPath </> "SimpleV2/all.script")

test_golden_SimpleScriptV2_Any :: TestTree
test_golden_SimpleScriptV2_Any =
testProperty "golden SimpleScriptV2 Any" $
goldenTestJsonValuePretty exampleSimpleScriptV2_Any (goldenPath </> "SimpleV2/any")
goldenTestJsonValuePretty exampleSimpleScriptV2_Any (goldenPath </> "SimpleV2/any.script")

test_golden_SimpleScriptV2_MofN :: TestTree
test_golden_SimpleScriptV2_MofN =
testProperty "golden SimpleScriptV2 MofN" $
goldenTestJsonValuePretty exampleSimpleScriptV2_MofN (goldenPath </> "SimpleV2/atleast")
goldenTestJsonValuePretty exampleSimpleScriptV2_MofN (goldenPath </> "SimpleV2/atleast.script")

test_roundtrip_SimpleScript_JSON :: TestTree
test_roundtrip_SimpleScript_JSON =
Expand Down
Loading
Loading