Skip to content

Commit

Permalink
Add module for UTxO type and operations
Browse files Browse the repository at this point in the history
  • Loading branch information
locallycompact committed Jan 6, 2025
1 parent a1a40fa commit 1e931e1
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 27 deletions.
3 changes: 3 additions & 0 deletions cardano-api/cardano-api.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ library internal
Cardano.Api.Query
Cardano.Api.Query.Expr
Cardano.Api.Query.Types
Cardano.Api.Query.UTxO
Cardano.Api.ReexposeConsensus
Cardano.Api.ReexposeLedger
Cardano.Api.ReexposeNetwork
Expand Down Expand Up @@ -227,6 +228,7 @@ library internal
transformers,
transformers-except ^>=0.1.3,
typed-protocols ^>=0.1.1,
unordered-containers,
vector,
yaml,

Expand All @@ -248,6 +250,7 @@ library
Cardano.Api.Ledger
Cardano.Api.Network
Cardano.Api.Shelley
Cardano.Api.UTxO

reexported-modules: Cardano.Api.Ledger.Lens
build-depends:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Cardano.Api.Eon.ShelleyBasedEra
import Cardano.Api.Fees
import Cardano.Api.ProtocolParameters
import Cardano.Api.Query
import Cardano.Api.Query.UTxO (UTxO (..))
import Cardano.Api.Tx.Body
import Cardano.Api.Tx.Sign
import Cardano.Api.Utils
Expand Down
1 change: 1 addition & 0 deletions cardano-api/internal/Cardano/Api/Convenience/Query.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import Cardano.Api.NetworkId
import Cardano.Api.ProtocolParameters
import Cardano.Api.Query
import Cardano.Api.Query.Expr
import Cardano.Api.Query.UTxO (UTxO)
import Cardano.Api.Tx.Body
import Cardano.Api.Utils

Expand Down
1 change: 1 addition & 0 deletions cardano-api/internal/Cardano/Api/Fees.hs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import Cardano.Api.Plutus
import Cardano.Api.Pretty
import Cardano.Api.ProtocolParameters
import Cardano.Api.Query
import Cardano.Api.Query.UTxO (UTxO (..))
import Cardano.Api.Script
import Cardano.Api.Tx.Body
import Cardano.Api.Tx.Sign
Expand Down
28 changes: 1 addition & 27 deletions cardano-api/internal/Cardano/Api/Query.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ module Cardano.Api.Query
, QueryInEra (..)
, QueryInShelleyBasedEra (..)
, QueryUTxOFilter (..)
, UTxO (..)
, UTxOInAnyEra (..)

-- * Internal conversion functions
Expand Down Expand Up @@ -77,6 +76,7 @@ import Cardano.Api.Modes
import Cardano.Api.NetworkId
import Cardano.Api.ProtocolParameters
import Cardano.Api.Query.Types
import Cardano.Api.Query.UTxO
import qualified Cardano.Api.ReexposeLedger as Ledger
import Cardano.Api.Tx.Body

Expand Down Expand Up @@ -115,10 +115,6 @@ import Ouroboros.Network.NodeToClient.Version (NodeToClientVersion (..
import Ouroboros.Network.Protocol.LocalStateQuery.Client (Some (..))

import Control.Monad.Trans.Except
import Data.Aeson (FromJSON (..), ToJSON (..), withObject)
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.KeyMap as KeyMap
import Data.Aeson.Types (Parser)
import Data.Bifunctor (bimap, first)
import qualified Data.ByteString.Lazy as LBS
import Data.Either.Combinators (rightToMaybe)
Expand Down Expand Up @@ -363,9 +359,6 @@ instance NodeToClientVersionOf QueryUTxOFilter where
newtype ByronUpdateState = ByronUpdateState Byron.Update.State
deriving Show

newtype UTxO era = UTxO {unUTxO :: Map TxIn (TxOut CtxUTxO era)}
deriving (Eq, Show)

data UTxOInAnyEra where
UTxOInAnyEra
:: CardanoEra era
Expand All @@ -374,25 +367,6 @@ data UTxOInAnyEra where

deriving instance Show UTxOInAnyEra

instance IsCardanoEra era => ToJSON (UTxO era) where
toJSON (UTxO m) = toJSON m
toEncoding (UTxO m) = toEncoding m

instance
(IsShelleyBasedEra era, FromJSON (TxOut CtxUTxO era))
=> FromJSON (UTxO era)
where
parseJSON = withObject "UTxO" $ \hm -> do
let l = toList $ KeyMap.toHashMapText hm
res <- mapM toTxIn l
pure . UTxO $ fromList res
where
toTxIn :: (Text, Aeson.Value) -> Parser (TxIn, TxOut CtxUTxO era)
toTxIn (txinText, txOutVal) = do
(,)
<$> parseJSON (Aeson.String txinText)
<*> parseJSON txOutVal

newtype SerialisedDebugLedgerState era
= SerialisedDebugLedgerState (Serialised (Shelley.NewEpochState (ShelleyLedgerEra era)))

Expand Down
1 change: 1 addition & 0 deletions cardano-api/internal/Cardano/Api/Query/Expr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import Cardano.Api.Keys.Shelley
import Cardano.Api.NetworkId
import Cardano.Api.ProtocolParameters
import Cardano.Api.Query
import Cardano.Api.Query.UTxO (UTxO)
import qualified Cardano.Api.ReexposeLedger as Ledger

import qualified Cardano.Ledger.Api as L
Expand Down
90 changes: 90 additions & 0 deletions cardano-api/internal/Cardano/Api/Query/UTxO.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}

module Cardano.Api.Query.UTxO where

import Cardano.Api.Eon.ShelleyBasedEra (IsShelleyBasedEra)
import Cardano.Api.Eras.Core (IsCardanoEra)
import Cardano.Api.Tx.Body (CtxUTxO, TxOut (..))
import Cardano.Api.TxIn (TxIn (..))

import Cardano.Ledger.Babbage ()

import Data.Aeson (FromJSON (..), ToJSON (..))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.KeyMap as KeyMap
import Data.Aeson.Types (Parser)
import qualified Data.HashMap.Strict as HashMap
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Set (Set)
import Data.Text (Text)
#if MIN_VERSION_base(4,17,0)
import GHC.IsList (IsList (..))
#endif

newtype UTxO era = UTxO {unUTxO :: Map TxIn (TxOut CtxUTxO era)}
deriving stock (Eq, Show)
deriving newtype (Semigroup, Monoid)
#if MIN_VERSION_base(4,17,0)
deriving newtype IsList
#endif

instance IsCardanoEra era => ToJSON (UTxO era) where
toJSON (UTxO m) = toJSON m
toEncoding (UTxO m) = toEncoding m

instance
IsShelleyBasedEra era
=> FromJSON (UTxO era)
where
parseJSON = Aeson.withObject "UTxO" $ \hm -> do
let l = HashMap.toList $ KeyMap.toHashMapText hm
res <- mapM toTxIn l
pure . UTxO $ Map.fromList res
where
toTxIn :: (Text, Aeson.Value) -> Parser (TxIn, TxOut CtxUTxO era)
toTxIn (txinText, txOutVal) = do
(,)
<$> parseJSON (Aeson.String txinText)
<*> parseJSON txOutVal

-- | Infix version of `difference`.
(\\) :: UTxO era -> UTxO era -> UTxO era
a \\ b = difference a b

-- | Create an empty `UTxO`.
empty :: UTxO era
empty = UTxO Map.empty

-- | Create a `UTxO` from a single unspent transaction output.
singleton :: TxIn -> TxOut CtxUTxO era -> UTxO era
singleton i o = UTxO $ Map.singleton i o

-- | Same as `lookup`.
resolve :: TxIn -> UTxO era -> Maybe (TxOut CtxUTxO era)
resolve = Cardano.Api.Query.UTxO.lookup

-- | Find a 'TxOut' for a given 'TxIn'.
lookup :: TxIn -> UTxO era -> Maybe (TxOut CtxUTxO era)
lookup k = Map.lookup k . unUTxO

-- | Filter all `TxOut` that satisfy the predicate.
filter :: (TxOut CtxUTxO era -> Bool) -> UTxO era -> UTxO era
filter fn = UTxO . Map.filter fn . unUTxO

-- | Filter all UTxO to only include 'out's satisfying given predicate.
filterWithKey :: (TxIn -> TxOut CtxUTxO era -> Bool) -> UTxO era -> UTxO era
filterWithKey fn = UTxO . Map.filterWithKey fn . unUTxO

-- | Get the 'UTxO domain input's set
inputSet :: UTxO (TxOut CtxUTxO era) -> Set TxIn
inputSet = Map.keysSet . unUTxO

-- | Remove the right hand side from the left hand side.
difference :: UTxO era -> UTxO era -> UTxO era
difference a b = UTxO $ Map.difference (unUTxO a) (unUTxO b)
1 change: 1 addition & 0 deletions cardano-api/src/Cardano/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,7 @@ import Cardano.Api.Protocol
import Cardano.Api.ProtocolParameters
import Cardano.Api.Query hiding (LedgerState (..))
import Cardano.Api.Query.Expr
import Cardano.Api.Query.UTxO (UTxO (..))
import Cardano.Api.Rewards
import Cardano.Api.Script
import Cardano.Api.ScriptData
Expand Down
3 changes: 3 additions & 0 deletions cardano-api/src/Cardano/Api/UTxO.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module Cardano.Api.UTxO (module Cardano.Api.Query.UTxO) where

import Cardano.Api.Query.UTxO

0 comments on commit 1e931e1

Please sign in to comment.