Skip to content

Commit

Permalink
Try #3507:
Browse files Browse the repository at this point in the history
  • Loading branch information
iohk-bors[bot] committed Sep 23, 2022
2 parents 944ef8b + ecba189 commit 3b66440
Show file tree
Hide file tree
Showing 35 changed files with 1,308 additions and 119 deletions.
29 changes: 17 additions & 12 deletions lib/wallet/cardano-wallet.cabal
Expand Up @@ -347,6 +347,22 @@ library
Cardano.Wallet.Primitive.Types.UTxOIndex.Internal
Cardano.Wallet.Primitive.Types.UTxOSelection
Cardano.Wallet.Primitive.Types.UTxOSelection.Gen
Cardano.Wallet.Read
Cardano.Wallet.Read.Eras
Cardano.Wallet.Read.Eras.EraFun
Cardano.Wallet.Read.Eras.EraValue
Cardano.Wallet.Read.Eras.InAnyCardanoEra
Cardano.Wallet.Read.Eras.KnownEras
Cardano.Wallet.Read.Primitive.Tx
Cardano.Wallet.Read.Primitive.Tx.Allegra
Cardano.Wallet.Read.Primitive.Tx.Alonzo
Cardano.Wallet.Read.Primitive.Tx.Babbage
Cardano.Wallet.Read.Primitive.Tx.Byron
Cardano.Wallet.Read.Primitive.Tx.Mary
Cardano.Wallet.Read.Primitive.Tx.Shelley
Cardano.Wallet.Read.Tx
Cardano.Wallet.Read.Tx.CBOR
Cardano.Wallet.Read.Tx.Hash
Cardano.Wallet.Registry
Cardano.Wallet.Shelley
Cardano.Wallet.Shelley.Api.Server
Expand Down Expand Up @@ -374,17 +390,6 @@ library
Cardano.Wallet.TokenMetadata
Cardano.Wallet.TokenMetadata.MockServer
Cardano.Wallet.Transaction
Cardano.Wallet.Types.Read
Cardano.Wallet.Types.Read.Primitive.Tx
Cardano.Wallet.Types.Read.Primitive.Tx.Allegra
Cardano.Wallet.Types.Read.Primitive.Tx.Alonzo
Cardano.Wallet.Types.Read.Primitive.Tx.Babbage
Cardano.Wallet.Types.Read.Primitive.Tx.Byron
Cardano.Wallet.Types.Read.Primitive.Tx.Mary
Cardano.Wallet.Types.Read.Primitive.Tx.Shelley
Cardano.Wallet.Types.Read.Tx
Cardano.Wallet.Types.Read.Tx.CBOR
Cardano.Wallet.Types.Read.Tx.Hash
Cardano.Wallet.Unsafe
Cardano.Wallet.Util
Cardano.Wallet.Version
Expand Down Expand Up @@ -776,7 +781,7 @@ test-suite unit
Cardano.Wallet.Shelley.NetworkSpec
Cardano.Wallet.Shelley.TransactionSpec
Cardano.Wallet.TokenMetadataSpec
Cardano.Wallet.Types.Read.Tx.CBORSpec
Cardano.Wallet.Read.Tx.CBORSpec
Cardano.WalletSpec
Control.Concurrent.ConciergeSpec
Control.Monad.Random.ExtraSpec
Expand Down
4 changes: 2 additions & 2 deletions lib/wallet/src/Cardano/Wallet.hs
Expand Up @@ -454,6 +454,8 @@ import Cardano.Wallet.Primitive.Types.UTxOIndex
( UTxOIndex )
import Cardano.Wallet.Primitive.Types.UTxOSelection
( UTxOSelection )
import Cardano.Wallet.Read.Tx.CBOR
( TxCBOR (..) )
import Cardano.Wallet.Transaction
( DelegationAction (..)
, ErrAssignRedeemers (..)
Expand All @@ -472,8 +474,6 @@ import Cardano.Wallet.Transaction
, defaultTransactionCtx
, withdrawalToCoin
)
import Cardano.Wallet.Types.Read.Tx.CBOR
( TxCBOR (..) )
import Control.Arrow
( first, left )
import Control.DeepSeq
Expand Down
2 changes: 1 addition & 1 deletion lib/wallet/src/Cardano/Wallet/Byron/Compatibility.hs
Expand Up @@ -63,7 +63,7 @@ import Cardano.Crypto.ProtocolMagic
( ProtocolMagicId, unProtocolMagicId )
import Cardano.Wallet.Primitive.Types.MinimumUTxO
( minimumUTxONone )
import Cardano.Wallet.Types.Read.Primitive.Tx.Byron
import Cardano.Wallet.Read.Primitive.Tx.Byron
( fromTxAux, fromTxIn, fromTxOut )
import Cardano.Wallet.Unsafe
( unsafeFromHex )
Expand Down
2 changes: 1 addition & 1 deletion lib/wallet/src/Cardano/Wallet/DB/Store/CBOR/Model.hs
Expand Up @@ -12,7 +12,7 @@ import Prelude

import Cardano.Wallet.DB.Sqlite.Types
( TxId )
import Cardano.Wallet.Types.Read.Tx.CBOR
import Cardano.Wallet.Read.Tx.CBOR
( TxCBOR )
import Data.Delta
( Delta (..) )
Expand Down
2 changes: 1 addition & 1 deletion lib/wallet/src/Cardano/Wallet/DB/Store/CBOR/Store.hs
Expand Up @@ -20,7 +20,7 @@ import Cardano.Wallet.DB.Sqlite.Types
( TxId (..) )
import Cardano.Wallet.DB.Store.CBOR.Model
( DeltaTxCBOR (..), TxCBORHistory (..) )
import Cardano.Wallet.Types.Read.Tx.CBOR
import Cardano.Wallet.Read.Tx.CBOR
( TxCBOR (..) )
import Data.ByteString.Lazy.Char8
( fromStrict, toStrict )
Expand Down
2 changes: 1 addition & 1 deletion lib/wallet/src/Cardano/Wallet/Primitive/Types/Tx.hs
Expand Up @@ -144,7 +144,7 @@ import Cardano.Wallet.Primitive.Types.Tx.Tx
)
import Cardano.Wallet.Primitive.Types.Tx.TxMeta
( Direction (..), TxMeta (..), TxStatus (..), isPending )
import Cardano.Wallet.Types.Read.Tx.CBOR
import Cardano.Wallet.Read.Tx.CBOR
( TxCBOR (..) )
import Data.Word
( Word64 )
Expand Down
Expand Up @@ -32,7 +32,7 @@ import Cardano.Wallet.Primitive.Types.Tx.Tx
( Tx (..), TxIn, TxMetadata, TxOut, TxScriptValidity )
import Cardano.Wallet.Primitive.Types.Tx.TxMeta
( TxMeta )
import Cardano.Wallet.Types.Read.Tx.CBOR
import Cardano.Wallet.Read.Tx.CBOR
( TxCBOR )
import Control.DeepSeq
( NFData (..) )
Expand Down
2 changes: 1 addition & 1 deletion lib/wallet/src/Cardano/Wallet/Primitive/Types/Tx/Tx.hs
Expand Up @@ -67,7 +67,7 @@ import Cardano.Wallet.Primitive.Types.TokenBundle
( TokenBundle (..) )
import Cardano.Wallet.Primitive.Types.TokenMap
( AssetId, Lexicographic (..) )
import Cardano.Wallet.Types.Read.Tx.CBOR
import Cardano.Wallet.Read.Tx.CBOR
( TxCBOR )
import Control.DeepSeq
( NFData (..) )
Expand Down
Expand Up @@ -9,11 +9,11 @@ This module re-exports the children of this module hierarchy
and is meant to be imported qualified, e.g.
@
import qualified Cardano.Wallet.Types.Read as Read
import qualified Cardano.Wallet.Read as Read
@
-}
module Cardano.Wallet.Types.Read
( module Cardano.Wallet.Types.Read.Tx
module Cardano.Wallet.Read
( module Cardano.Wallet.Read.Tx
) where

import Cardano.Wallet.Types.Read.Tx
import Cardano.Wallet.Read.Tx
71 changes: 71 additions & 0 deletions lib/wallet/src/Cardano/Wallet/Read/Eras.hs
@@ -0,0 +1,71 @@

-- |
-- Copyright: © 2020-2022 IOHK
-- License: Apache-2.0
--
-- Re-export `EraValue` library.
--

module Cardano.Wallet.Read.Eras
( -- * Eras.
KnownEras
, knownEraIndices
-- * Era bounded values.
, EraValue
, eraValueSerialize
, extractEraValue
-- * Era specific prisms.
, MkEraValue (..)
, byron
, shelley
, allegra
, mary
, alonzo
, babbage
-- * Era specific prism shortcuts.
, inject
, project
-- * Specials.
, sequenceEraValue
-- * Era bounded functions.
, EraFun (..)
-- * Composing era functions.
, (*.**)
, (*&&&*)
-- * Applying era functions.
, applyEraFun
-- * Reexports from elsewhere.
, (:.:)(..)
, K (..)
, unK
, (:*:)(..)
-- * Conversion.
, isoInAnyCardanoEra
)
where

import Cardano.Wallet.Read.Eras.EraFun
( EraFun (..), applyEraFun, (*&&&*), (*.**) )
import Cardano.Wallet.Read.Eras.EraValue
( EraValue
, MkEraValue (..)
, allegra
, alonzo
, babbage
, byron
, eraValueSerialize
, extractEraValue
, inject
, mary
, project
, sequenceEraValue
, shelley
)
import Cardano.Wallet.Read.Eras.InAnyCardanoEra
( isoInAnyCardanoEra )
import Cardano.Wallet.Read.Eras.KnownEras
( KnownEras, knownEraIndices )
import Generics.SOP
( (:.:) (..), K (..), unK )
import GHC.Generics
( (:*:) (..) )
162 changes: 162 additions & 0 deletions lib/wallet/src/Cardano/Wallet/Read/Eras/EraFun.hs
@@ -0,0 +1,162 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}

-- |
-- Copyright: © 2020-2022 IOHK
-- License: Apache-2.0
--
-- A datatype that represents a vector of functions covering all known eras
-- The functions are supposed to map values from and to the same era.
--
-- We removed the cached encoding at the price of 'toEraFun' and 'fromEraFun'
-- during all compositions, we are not 100% it's not relevant for performance
-- If the computed functions after record compositions are the same then we can
-- avoid that layer
--
-- Note composition is anyway expansive, do not recompose,
-- just cache and reuse the compositions
--

module Cardano.Wallet.Read.Eras.EraFun
( -- * Types.
EraFun (..)
-- * Composition.
, (*.**)
, (*&&&*)
-- * Application.
, applyEraFun
-- * Constant era 'EraFun'
, EraFunK (..)
)
where

import Prelude hiding
( id, (.) )

import Cardano.Api
( AllegraEra, AlonzoEra, BabbageEra, ByronEra, MaryEra, ShelleyEra )
import Cardano.Wallet.Read.Eras.EraValue
( EraValue (..) )
import Cardano.Wallet.Read.Eras.KnownEras
( KnownEras )
import Control.Category
( Category (..) )
import Generics.SOP
( (:.:) (..)
, I (..)
, K (..)
, NP
, Proxy (Proxy)
, productTypeFrom
, productTypeTo
, unComp
, unK
)
import Generics.SOP.Classes
import Generics.SOP.NP
( map_NP, pure_NP, trans_NP, zipWith_NP )
import Generics.SOP.NS
( ap_NS )
import Generics.SOP.TH
( deriveGeneric )
import GHC.Generics
( (:*:) (..) )

-- | A record of functions indexed by all known eras. This is the natural way
-- of defining the vector.
data EraFun f g = EraFun
{ byronFun :: f ByronEra -> g ByronEra
, shelleyFun :: f ShelleyEra -> g ShelleyEra
, allegraFun :: f AllegraEra -> g AllegraEra
, maryFun :: f MaryEra -> g MaryEra
, alonzoFun :: f AlonzoEra -> g AlonzoEra
, babbageFun :: f BabbageEra -> g BabbageEra
}

deriveGeneric ''EraFun
-- | A product of functions indexed by KnownEras.
type EraFunI f g = NP (f -.-> g) KnownEras

-- | Apply an 'EraFun' to an 'EraValue'.
-- Because EraValue is a value in a specific era, the application will choose
-- the correct function from the vector.
-- In case of repeated application use this function curried on the 'EraFun'
-- argument, this will avoid the recomputation of the core
applyEraFun :: EraFun f g -> EraValue f -> EraValue g
applyEraFun f = let
g = fromEraFun f -- curry friendly
in \(EraValue v) -> EraValue $ ap_NS g v

class CR f g x y where
unC :: I x -> (f -.-> g) y
instance CR f g (f era -> g era) era where
unC (I f) = Fn f

-- Promote an 'EraFun'.
fromEraFun :: forall f g . EraFun f g -> EraFunI f g
fromEraFun = trans_NP (Proxy @(CR f g)) unC . productTypeFrom

class DR f g x y where
unD :: (f -.-> g) x -> I y
instance DR f g era (f era -> g era) where
unD (Fn f) = I f

-- Project out to an 'EraFun'.
toEraFun :: forall f g. EraFunI f g -> EraFun f g
toEraFun = productTypeTo . trans_NP (Proxy @(DR f g)) unD

instance Category EraFun where
id = toEraFun $ pure_NP $ Fn id
f . g = toEraFun
$ zipWith_NP (\(Fn f') (Fn g') -> Fn $ f' . g')
(fromEraFun f) (fromEraFun g)

infixr 9 *.**

-- | Compose 2 EraFunI as a category, jumping the outer functorial layer in the
-- output of the first one.
(*.**) :: Functor w => EraFunI g h -> EraFunI f (w :.: g) -> EraFunI f (w :.: h)
(*.**) = composeEraFunWith $ \f' g' -> Comp . fmap f' . unComp . g'

-- | Compose 2 EraFunI as a category, keeping the outer layer in the
-- output of the first one.
composeEraFunWith
:: (forall a . (g a -> h a) -> (f a -> w g a) -> f a -> w h a)
-> EraFunI g h
-> EraFunI f (w g)
-> EraFunI f (w h)
composeEraFunWith q = zipWith_NP (\(Fn f') (Fn g') -> Fn $ q f' g')

infixr 9 *&&&*

-- | Compose 2 EraFunI as parallel application using '(:*:)'.
(*&&&*) :: EraFun f g -> EraFun f h -> EraFun f (g :*: h)
f *&&&* g = toEraFun $ zipWith_NP r (fromEraFun f) (fromEraFun g)
where
r (Fn f') (Fn g') = Fn $ \x -> f' x :*: g' x

newtype EraFunK src ft = EraFunK (EraFun src (K ft))

instance Functor (EraFunK src) where
fmap :: forall a b . (a -> b) -> EraFunK src a -> EraFunK src b
fmap f (EraFunK g)
= EraFunK (toEraFun $ map_NP q $ fromEraFun g )
where
q :: (-.->) src (K a) era -> (-.->) src (K b) era
q (Fn h) = Fn $ \x -> K . f $ unK $ h x

instance Applicative (EraFunK src) where
pure x = EraFunK $ toEraFun $ pure_NP $ Fn $ \_ -> K x
EraFunK f <*> EraFunK g =
EraFunK $ toEraFun $ zipWith_NP q (fromEraFun f) (fromEraFun g)
where
q (Fn h) (Fn j) = Fn $ \src -> K $ unK (h src) $ unK $ j src

0 comments on commit 3b66440

Please sign in to comment.