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

Restructure the Core for consistency, clarity and new functionality #2901

Merged
merged 2 commits into from
Jul 27, 2022

Commits on Jul 26, 2022

  1. Restructure the Core for consistency, clarity and new functionality

    **Creation of class hierarchy**
    
    **New classes**
    
    ```
    EraSegWits --> EraTx --> EraTxBody --> EraTxOut --> Era
                         \              `--> EraPParams --> Era
                           `--> EraWitnesses --> EraScript --> Era
                            `--> EraAuxiliaryData --> Era
    ```
    
    Note that all of the `Era*` classes have a few properties:
    
    * depend either directly or transitively on the `Era` type class.
    * define an associated type family (which was previously standalone).
    * add all constraints that the associated type must implement.
    
    This means that any function that uses an associated type family can safely use
    the corresponding type class. For example a function that accepts `TxBody` as
    argument can always set `EraTx` as a constraint, which will bring all of the
    superclasses as constraints as well.
    
    Loose corespondance of new classes to the old removed concepts:
    
    * `Era` class is the same as before with the addition of type level protocol
      version and deprecation of all of the functions. It also implements now a per era
      deprecation mechanism with protocol version bounds
    * `EraTxOut` has  all superclasses as in `UsesTxOut` type  synonym constraint as
      well  as defines  lenses that  supercede all  functions previously  defined in
      `Era` type class
    * `EraTxBody` has all superclasses as in `UsesTxBody` type synonym constraint
    * `EraAuxiliaryData` has all superclasses as in `UsesAuxiliaryData` type synonym
      constraint and consolidates `ValidateAuxiliaryData` into it
    * `EraPParams` replaces `UsesPParams` type class now with an associated type family
    * `EraScript` has replaced `UsesScript` type synonym constraint and the
      `ValidateScripts` type class, with an exception of `validateScript` function,
      which was moved into `EraTx` type class, since it depends on the `Tx`
    
    **Lenses**
    
    This PR expands usage of
    [`microlens`](https://hackage.haskell.org/package/microlens) package.
    
    Each class defines lenses for associated types, all of which are getters and
    potentially setter. They also define a way to construct a minimal value of an
    asscoiated type. For example if we want to construct a function that will
    construct a `Tx` with a new `TxBody`, which uses `AuxiliaryData` from another
    `Tx`:
    
    ```haskell
    newTxWithOtherAuxData :: EraTx era => TxBody era -> Tx era -> Tx era
    newTxWithOtherAuxData txBody tx =
      mkBasicTx txBody & auxDataTxL .~ (tx ^. auxDataTxL)
    ```
    
    Above function is guaranteed to work with transactions of all eras.
    
    Some are just getters, which simply relay some information from one or more
    fields of a concrete type, altohugh they might do some minimal computation. For
    example `allInputsTxBodyF` will return all of the inputs present in the
    `TxBody`.
    
    **Naming convention**
    
    All lenses are suffixed with the type name they operate on and either `L`ens or `G`etter.
    
    **Migration guide**
    
    **Accessor fields**
    
    Names suffered some very minor adjustments that don't match the spec (tagged with *)
    
    **TxOut**
    
    * `makeTxOut (Proxy era)` -> `mkBasicTxOut`
    * `getField @"value" txOut` -> `txOut ^. valueTxOutL`
    * `_` -> `txOut ^. compactValueTxOutL`
    * `getCoin` -> `txOut ^. coinTxOutL`
    * `getTxOutAddr txOut` -> `txOut ^. addrTxOutL`
    * `getTxOutEitherAddr txOut` -> `txOut ^. addrEitherTxOutL`
    * `getTxOutCompactAddr txOut` -> `txOut ^. compactAddrTxOutL`
    * `getTxOutBootstrapAddress txOut` -> `txOut ^. bootAddrTxOutF`
    
    * `getField @"datahash" txOut` -> `txOut ^. dataHashTxOutL` (*)
    * `getField @"referenceScript" txOut` -> `txOut ^. referenceScriptTxOutL`
    * `_` -> `txOut ^. dataTxOutL`
    * `_` -> `txOut ^. datumTxOutL`
    
    **TxBody**
    
    * `getField @"inputs" txBody` -> ` txBody ^. inputsTxBodyL`
    * `getField @"outputs" txBody` -> ` txBody ^. outputsTxBodyL`
    * `getField @"txfee" txBody` -> ` txBody ^. feeTxBodyL` (*)
    * `getField @"auxiliaryData" txBody` -> ` txBody ^. auxDataHashTxBodyL` (*)
    * `getAllInputs txBody` -> ` txBody ^. allInputsTxBodyF`
    * `getField @"minted" txBody` -> ` txBody ^. mintedTxBodyF`
    
    * `getField @"wdrls" txBody` -> `txBody ^. wdrlsTxBodyL`
    * `getField @"ttl" txBody` -> `txBody ^. ttlTxBodyL`
    * `getField @"update" txBody` -> `txBody ^. updateTxBodyL`
    * `getField @"certs" txBody` -> `txBody ^. certsTxBodyL`
    * `getField @"vldt" txBody` -> `txBody ^. vldtTxBodyL`
    * `getField @"mint" txBody` -> `txBody ^. mintTxBodyL`
    * `getField @"collateral" txBody` -> `txBody ^. collateralInputsTxBodyL` (*)
    * `getField @"reqSignerHashes" txBody` -> `txBody ^. reqSignerHashesTxBodyL`
    * `getField @"scriptIntegrityHash" txBody` -> `txBody ^. scriptIntegrityHashTxBodyL`
    * `getField @"txnetworkid" txBody` -> `txBody ^. networkIdTxBodyL` (*)
    
    * `getField @"sizedOutputs" txBody` -> `txBody ^. sizedOutputsTxBodyL`
    * `getField @"referenceInputs" txBody` -> `txBody ^. referenceInputsTxBodyL`
    * `getField @"totalCollateral" txBody` -> `txBody ^. totalCollateralTxBodyL`
    * `getField @"collateralReturn" txBody` -> `txBody ^. collateralReturnTxBodyL`
    * `getField @"sizedCollateralReturn" txBody` -> `txBody ^. sizedCollateralReturnTxBodyL`
    
    **Tx**
    
    * `getField @"body" tx` -> `tx ^. bodyTxL`
    * `getField @"wits" tx` -> `tx ^. witsTxL`
    * `getField @"auxData" tx` -> `tx ^. auxDataTxL`
    * `getField @"size" tx` -> `tx ^. sizeTxF`
    * `getField @"isValid" tx` -> `tx ^. isValidTxL`
    
    Nested instances are no longer needed, since composition of lenses works much better:
    
    * `getField @"addrWits" tx` -> `tx ^. witsTxL . addrWitsL`
    * `getField @"scriptWits" tx` -> `tx ^. witsTxL . scriptsWitsL`
    * `getField @"bootWits" tx` -> `tx ^. witsTxL . bootAddrWitsL`
    * `getField @"txdatahash" tx` -> `tx ^. witsTxL . datsWitsL . to unTxDats`
    
    **Witnesses**
    
    * `getField @"addr" txWits` -> `txWits ^. addrWitsL`
    * `getField @"bootAddr" txWits` -> `txWits ^. bootAddrWitsL`
    * `getField @"script" txWits` -> `txWits ^. scriptWitsL`
    * `getField @"dats" txWits` -> `txWits ^. datsWitsL`
    * `getField @"rdmrs" txWits` -> `txWits ^. rdmrsWitsL`
    
    **Removal of constraint type synonyms**
    
    All of the `Trans*`, `Uses*` constraints have been removed as they are fully
    replaced by the above hierarchy
    
    Names removed and their closest replacements:
    
    * `BlockAnn` -> `EraTx`
    * `ChainData` - no replacemnt, this was just an adhoc collection of classes
        SerialisableData,
    * `AnnotatedData` -> `FromCBOR (Annotator t)` + `ToCBOR t`
    * `SerialisableData` -> `FromCBOR t` + `ToCBOR t`
    * `WellFormed` -> `EraTx`
    * `ShelleyEraCrypto`
    
    **`Val` class**
    
    Addition of two class methods that allow efficient manipulation of compact coin
    representation: `injectCompact` and `modifyCompactCoin`, without uncompacting
    the actual type `t` for which the `Val` instance is being defined
    
    **Data type renaming**
    
    All concrete types for every era where either inconsistent or clashing with the
    core type families:
    
    * Before this commit:
    
    | Core          | Shelley       | ShelleyMA       | Alonzo        | Babbage       |
    |:-------------:|:-------------:|:---------------:|:-------------:|:-------------:|
    | Tx            | Tx            |    --           | ValidatedTx   |    --         |
    | TxBody        | TxBody        | MATxBody        | TxBody        | TxBody        |
    | TxOut         | TxOut         |    --           | TxOut         | TxOut         |
    | AuxiliaryData | AuxiliaryData | MAAuxiliaryData | AuxiliaryData |    --         |
    | Witnesses     | WitnessSetHKD |    --           | TxWitness     |    --         |
    | Script        | MultiSig      | Timelock        | Script        |    --         |
    | Value         | Coin          | Value           | --            |    --         |
    | PParams       | PParams       |    --           | PParams       | PParams       |
    | PParamsDelta  | PParamsUpdate |    --           | PParamsUpdate | PParamsUpdate |
    
    * After this commit
    
    | Core          | Shelley              | ShelleyMA       | Alonzo              | Babbage              |
    |:-------------:|:--------------------:|:---------------:|:-------------------:|:--------------------:|
    | Tx            | ShelleyTx            |    --           | AlonzoTx            |    --                |
    | TxBody        | ShelleyTxBody        | MATxBody        | AlonzoTxBody        | BabbageTxBody        |
    | TxOut         | ShelleyTxOut         |    --           | AlonzoTxOut         | BabbageTxOut         |
    | AuxiliaryData | ShelleyAuxiliaryData | MAAuxiliaryData | AlonzoAuxiliaryData |    --                |
    | Witnesses     | WitnessSetHKD        |    --           | TxWitness           |    --                |
    | Script        | MultiSig             | Timelock        | AlonzoScript        |    --                |
    | Value         | Coin                 | MaryValue       | --                  |    --                |
    | PParams       | ShelleyPParams       |    --           | AlonzoPParams       | BabbagePParams       |
    | PParamsUpdate | ShelleyPParamsUpdate |    --           | AlonzoPParamsUpdate | BabbagePParamsUpdate |
    
    **Module restructure**
    
    Concrete era data type (eg. `BabageEra`) is no longer defined at the top level
    module (eg. `Cardano.Ledger.Babbage`), but rather in a new private `.Era` module
    (eg. `Cardano.Ledger.Babbage.Era`). It is later re-exported from the top level
    module together with all of the orphan instances. This allows us to define all
    of the relevant instances in their respective modules (eg. `EraTxBody` is defined
    in the `TxBody` module)
    
    **Other minor changes**
    
    * Defined `NFData` for `Sized`
    * Rename `Cardano.Ledger.Shelley.Core` to `Cardano.Ledger.Shelley.Type`
    * Move module `Cardano.Ledger.Shelley.Address.Bootstrap`
      (`cardano-ledger-shelley`) -> `Cardano.Ledger.Keys.Bootstrap` (`cardano-ledger-core`)
    * Moved `langsUsed` into tests, since that was the only use site.
    lehins committed Jul 26, 2022
    Configuration menu
    Copy the full SHA
    acd88e8 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    73b77de View commit details
    Browse the repository at this point in the history