Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information