Skip to content

Commit c4f649f

Browse files
authored
Remove the deriving-aeson dependency (#7871)
* Add tests for cost model JSON encoding stability Compare the serialized form of BuiltinCostModelBase and CekMachineCostsBase against the checked-in cost-model/data files for every semantics variant, and cover the field-omitting instances used by generate-cost-model. Differences are reported as a JSON patch so that a failure names the offending entries instead of printing both cost models in full. * Remove the deriving-aeson dependency Replace the CustomJSON deriving-via JSON instances of the cost model types with plain aeson generic instances (genericToJSON, genericToEncoding, genericParseJSON with explicit Options). The JSON format is unchanged. Drops the allow-newer exception for deriving-aeson:aeson from cabal.project. Issue: #7870
1 parent b9d726d commit c4f649f

10 files changed

Lines changed: 343 additions & 212 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
### Removed
2+
3+
- `LowerInitialCharacter` is no longer exported from `PlutusCore.Evaluation.Machine.ExBudget`; it existed solely to support `deriving-aeson`, which `plutus-core` no longer depends on.
4+
5+
### Changed
6+
7+
- Replaced the `deriving-aeson`-based JSON instances of the cost model types with plain `aeson` generic instances. The JSON format is unchanged.

plutus-core/cost-model/CostModelGeneration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ our case, the costing function is given by the
292292
type. The type prefix `ModelTwoArguments` is removed from the
293293
constructor name and the remaining `MinSize` is converted to
294294
`min_size` by the Aeson library's
295-
[`CamelToSnake`](https://hackage.haskell.org/package/deriving-aeson-0.2.8/docs/Deriving-Aeson.html#t:CamelToSnake)
295+
[`camelTo2`](https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#v:camelTo2)
296296
transformation. Similarly, the names of the
297297
`modelMinSizeIntercept` and `modelMinSizeSlope` fields in the
298298
`ModelMinSize` type are converted to `slope` and `intercept`. In

plutus-core/plutus-core.cabal

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,6 @@ library
327327
, data-default-class
328328
, deepseq
329329
, dependent-sum >=0.7.1.0
330-
, deriving-aeson >=0.2.3
331330
, deriving-compat
332331
, dlist
333332
, exceptions
@@ -382,6 +381,7 @@ test-suite plutus-core-test
382381
CBOR.DataStability
383382
Check.Spec
384383
CostModelInterface.Spec
384+
CostModelJSON.Spec
385385
CostModelSafety.Spec
386386
Evaluation.Machines
387387
Evaluation.Spec
@@ -398,6 +398,9 @@ test-suite plutus-core-test
398398
default-language: Haskell2010
399399
build-depends:
400400
, aeson
401+
, aeson-diff
402+
, aeson-pretty
403+
, barbies
401404
, base >=4.9 && <5
402405
, base16-bytestring ^>=1.0
403406
, bytestring

plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
-- editorconfig-checker-disable-file
22
{-# LANGUAGE ConstraintKinds #-}
3-
{-# LANGUAGE DataKinds #-}
43
{-# LANGUAGE DeriveAnyClass #-}
54
{-# LANGUAGE FlexibleInstances #-}
65
{-# LANGUAGE StrictData #-}
@@ -57,13 +56,12 @@ import PlutusPrelude hiding (toList)
5756

5857
import PlutusCore.Evaluation.Machine.CostingFun.Core
5958
import PlutusCore.Evaluation.Machine.CostingFun.JSON ()
60-
import PlutusCore.Evaluation.Machine.ExBudget
6159

6260
import Barbies
6361
import Data.Aeson
6462
import Data.Kind qualified as Kind
63+
import Data.List (stripPrefix)
6564
import Data.Monoid
66-
import Deriving.Aeson
6765
import Language.Haskell.TH.Syntax hiding (Name, newName)
6866

6967
type BuiltinCostModel = BuiltinCostModelBase CostingFun
@@ -203,18 +201,21 @@ data BuiltinCostModelBase f
203201
deriving stock (Generic)
204202
deriving anyclass (FunctorB, TraversableB, ConstraintsB)
205203

206-
deriving via
207-
CustomJSON
208-
'[FieldLabelModifier (StripPrefix "param", LowerInitialCharacter)]
209-
(BuiltinCostModelBase CostingFun)
210-
instance
211-
ToJSON (BuiltinCostModelBase CostingFun)
212-
deriving via
213-
CustomJSON
214-
'[FieldLabelModifier (StripPrefix "param", LowerInitialCharacter)]
215-
(BuiltinCostModelBase CostingFun)
216-
instance
217-
FromJSON (BuiltinCostModelBase CostingFun)
204+
{-| JSON options for 'BuiltinCostModelBase': drop the @param@ prefix and lower the initial
205+
character, so that the names of the JSON fields are exactly the same as the names of the
206+
builtins. -}
207+
builtinCostModelOptions :: Options
208+
builtinCostModelOptions =
209+
defaultOptions {fieldLabelModifier = lowerInitialChar . dropPrefix "param"}
210+
where
211+
dropPrefix prefix s = fromMaybe s (stripPrefix prefix s)
212+
213+
instance ToJSON (BuiltinCostModelBase CostingFun) where
214+
toJSON = genericToJSON builtinCostModelOptions
215+
toEncoding = genericToEncoding builtinCostModelOptions
216+
217+
instance FromJSON (BuiltinCostModelBase CostingFun) where
218+
parseJSON = genericParseJSON builtinCostModelOptions
218219

219220
{-| Same as 'CostingFun' but maybe missing.
220221
We could use 'Compose Maybe CostinFun' instead but we would then need an orphan ToJSON instance. -}
@@ -223,12 +224,12 @@ newtype MCostingFun a = MCostingFun (Maybe (CostingFun a))
223224
deriving (Semigroup, Monoid) via (Alt Maybe (CostingFun a)) -- for mempty == MCostingFun Nothing
224225

225226
-- Omit generating JSON for any costing functions that have not been set (are missing).
226-
deriving via
227-
CustomJSON
228-
'[OmitNothingFields, FieldLabelModifier (StripPrefix "param", LowerInitialCharacter)]
229-
(BuiltinCostModelBase MCostingFun)
230-
instance
231-
ToJSON (BuiltinCostModelBase MCostingFun)
227+
instance ToJSON (BuiltinCostModelBase MCostingFun) where
228+
toJSON = genericToJSON mBuiltinCostModelOptions
229+
toEncoding = genericToEncoding mBuiltinCostModelOptions
230+
231+
mBuiltinCostModelOptions :: Options
232+
mBuiltinCostModelOptions = builtinCostModelOptions {omitNothingFields = True}
232233

233234
-- Needed to help derive various instances for BuiltinCostModelBase
234235
type AllArgumentModels (constraint :: Kind.Type -> Kind.Constraint) f =

plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/Core.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ import PlutusCore.Evaluation.Machine.ExMemoryUsage
5959
import Control.DeepSeq
6060
import Data.Default.Class
6161
import Data.Hashable
62-
import Deriving.Aeson
6362
import GHC.Exts
63+
import GHC.Generics (Generic)
6464
import Language.Haskell.TH.Syntax hiding
6565
( Name
6666
, newName

0 commit comments

Comments
 (0)