{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Cardano.Wallet.CoinSelection.Internal.Balance
(
PerformSelection
, performSelection
, performSelectionEmpty
, SelectionConstraints (..)
, SelectionParams
, SelectionParamsOf (..)
, SelectionSkeleton (..)
, SelectionResult
, SelectionResultOf (..)
, SelectionStrategy (..)
, SelectionBalanceError (..)
, BalanceInsufficientError (..)
, UnableToConstructChangeError (..)
, SelectionLimit
, SelectionLimitOf (..)
, selectionLimitExceeded
, SelectionLimitReachedError (..)
, reduceSelectionLimitBy
, SelectionDelta (..)
, selectionDeltaAllAssets
, selectionDeltaCoin
, selectionHasValidSurplus
, selectionSurplusCoin
, selectionMinimumCost
, selectionMaximumCost
, selectionSkeleton
, UTxOBalanceSufficiency (..)
, UTxOBalanceSufficiencyInfo (..)
, computeBalanceInOut
, computeDeficitInOut
, computeUTxOBalanceAvailable
, computeUTxOBalanceRequired
, computeUTxOBalanceSufficiency
, computeUTxOBalanceSufficiencyInfo
, isUTxOBalanceSufficient
, runSelection
, runSelectionNonEmpty
, runSelectionNonEmptyWith
, RunSelectionParams (..)
, runSelectionStep
, SelectionLens (..)
, assetSelectionLens
, coinSelectionLens
, MakeChangeCriteria (..)
, makeChange
, makeChangeForCoin
, makeChangeForUserSpecifiedAsset
, makeChangeForNonUserSpecifiedAsset
, makeChangeForNonUserSpecifiedAssets
, assignCoinsToChangeMaps
, collateNonUserSpecifiedAssetQuantities
, addMintValueToChangeMaps
, addMintValuesToChangeMaps
, removeBurnValueFromChangeMaps
, removeBurnValuesFromChangeMaps
, reduceTokenQuantities
, splitBundleIfAssetCountExcessive
, splitBundlesWithExcessiveAssetCounts
, splitBundlesWithExcessiveTokenQuantities
, groupByKey
, ungroupByKey
, runRoundRobin
, runRoundRobinM
, AssetCount (..)
, distance
, mapMaybe
, balanceMissing
) where
import Prelude
import Algebra.PartialOrd
( PartialOrd (..) )
import Cardano.Numeric.Util
( padCoalesce )
import Cardano.Wallet.CoinSelection.Internal.Context
( SelectionContext (..) )
import Cardano.Wallet.Primitive.Types.Coin
( Coin (..) )
import Cardano.Wallet.Primitive.Types.TokenBundle
( TokenBundle (..) )
import Cardano.Wallet.Primitive.Types.TokenMap
( AssetId, Lexicographic (..), TokenMap )
import Cardano.Wallet.Primitive.Types.TokenQuantity
( TokenQuantity (..) )
import Cardano.Wallet.Primitive.Types.Tx
( TokenBundleSizeAssessment (..), TokenBundleSizeAssessor (..) )
import Cardano.Wallet.Primitive.Types.UTxOIndex
( Asset (..), SelectionFilter (..), UTxOIndex (..) )
import Cardano.Wallet.Primitive.Types.UTxOSelection
( IsUTxOSelection, UTxOSelection, UTxOSelectionNonEmpty )
import Control.Monad.Extra
( andM )
import Control.Monad.Random.Class
( MonadRandom (..) )
import Data.Bifunctor
( first )
import Data.Either.Extra
( maybeToEither )
import Data.Function
( (&) )
import Data.Functor.Identity
( Identity (..) )
import Data.Generics.Internal.VL.Lens
( view )
import Data.Generics.Labels
()
import Data.IntCast
( intCast )
import Data.List.NonEmpty
( NonEmpty (..) )
import Data.Map.Strict
( Map )
import Data.Maybe
( fromMaybe )
import Data.Ord
( comparing )
import Data.Semigroup
( mtimesDefault )
import Data.Set
( Set )
import Fmt
( Buildable (..), Builder, blockMapF )
import GHC.Generics
( Generic )
import GHC.Stack
( HasCallStack )
import Numeric.Natural
( Natural )
import qualified Cardano.Wallet.Primitive.Types.Coin as Coin
import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle
import qualified Cardano.Wallet.Primitive.Types.TokenMap as TokenMap
import qualified Cardano.Wallet.Primitive.Types.TokenQuantity as TokenQuantity
import qualified Cardano.Wallet.Primitive.Types.UTxOIndex as UTxOIndex
import qualified Cardano.Wallet.Primitive.Types.UTxOSelection as UTxOSelection
import qualified Data.Foldable as F
import qualified Data.List as L
import qualified Data.List.NonEmpty as NE
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
data SelectionConstraints ctx = SelectionConstraints
{ SelectionConstraints ctx
-> TokenBundle -> TokenBundleSizeAssessment
assessTokenBundleSize
:: TokenBundle -> TokenBundleSizeAssessment
, SelectionConstraints ctx -> Address ctx -> TokenMap -> Coin
computeMinimumAdaQuantity
:: Address ctx -> TokenMap -> Coin
, SelectionConstraints ctx -> SelectionSkeleton ctx -> Coin
computeMinimumCost
:: SelectionSkeleton ctx -> Coin
, SelectionConstraints ctx
-> [(Address ctx, TokenBundle)] -> SelectionLimit
computeSelectionLimit
:: [(Address ctx, TokenBundle)] -> SelectionLimit
, SelectionConstraints ctx -> Address ctx
maximumLengthChangeAddress
:: Address ctx
, SelectionConstraints ctx -> Coin
maximumOutputAdaQuantity
:: Coin
, SelectionConstraints ctx -> TokenQuantity
maximumOutputTokenQuantity
:: TokenQuantity
, SelectionConstraints ctx -> Address ctx
nullAddress
:: Address ctx
}
deriving (forall x.
SelectionConstraints ctx -> Rep (SelectionConstraints ctx) x)
-> (forall x.
Rep (SelectionConstraints ctx) x -> SelectionConstraints ctx)
-> Generic (SelectionConstraints ctx)
forall x.
Rep (SelectionConstraints ctx) x -> SelectionConstraints ctx
forall x.
SelectionConstraints ctx -> Rep (SelectionConstraints ctx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall ctx x.
Rep (SelectionConstraints ctx) x -> SelectionConstraints ctx
forall ctx x.
SelectionConstraints ctx -> Rep (SelectionConstraints ctx) x
$cto :: forall ctx x.
Rep (SelectionConstraints ctx) x -> SelectionConstraints ctx
$cfrom :: forall ctx x.
SelectionConstraints ctx -> Rep (SelectionConstraints ctx) x
Generic
type SelectionParams = SelectionParamsOf []
data SelectionParamsOf f ctx = SelectionParams
{ SelectionParamsOf f ctx -> f (Address ctx, TokenBundle)
outputsToCover
:: !(f (Address ctx, TokenBundle))
, SelectionParamsOf f ctx -> UTxOSelection (UTxO ctx)
utxoAvailable
:: !(UTxOSelection (UTxO ctx))
,
:: !Coin
,
:: !Coin
, SelectionParamsOf f ctx -> TokenMap
assetsToMint
:: !TokenMap
, SelectionParamsOf f ctx -> TokenMap
assetsToBurn
:: !TokenMap
, SelectionParamsOf f ctx -> SelectionStrategy
selectionStrategy
:: SelectionStrategy
}
deriving (forall x.
SelectionParamsOf f ctx -> Rep (SelectionParamsOf f ctx) x)
-> (forall x.
Rep (SelectionParamsOf f ctx) x -> SelectionParamsOf f ctx)
-> Generic (SelectionParamsOf f ctx)
forall x.
Rep (SelectionParamsOf f ctx) x -> SelectionParamsOf f ctx
forall x.
SelectionParamsOf f ctx -> Rep (SelectionParamsOf f ctx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (f :: * -> *) ctx x.
Rep (SelectionParamsOf f ctx) x -> SelectionParamsOf f ctx
forall (f :: * -> *) ctx x.
SelectionParamsOf f ctx -> Rep (SelectionParamsOf f ctx) x
$cto :: forall (f :: * -> *) ctx x.
Rep (SelectionParamsOf f ctx) x -> SelectionParamsOf f ctx
$cfrom :: forall (f :: * -> *) ctx x.
SelectionParamsOf f ctx -> Rep (SelectionParamsOf f ctx) x
Generic
deriving instance
(Eq (f (Address ctx, TokenBundle)), Eq (UTxO ctx)) =>
Eq (SelectionParamsOf f ctx)
deriving instance
(Show (f (Address ctx, TokenBundle)), Show (UTxO ctx)) =>
Show (SelectionParamsOf f ctx)
data SelectionStrategy
= SelectionStrategyMinimal
| SelectionStrategyOptimal
deriving (SelectionStrategy
SelectionStrategy -> SelectionStrategy -> Bounded SelectionStrategy
forall a. a -> a -> Bounded a
maxBound :: SelectionStrategy
$cmaxBound :: SelectionStrategy
minBound :: SelectionStrategy
$cminBound :: SelectionStrategy
Bounded, Int -> SelectionStrategy
SelectionStrategy -> Int
SelectionStrategy -> [SelectionStrategy]
SelectionStrategy -> SelectionStrategy
SelectionStrategy -> SelectionStrategy -> [SelectionStrategy]
SelectionStrategy
-> SelectionStrategy -> SelectionStrategy -> [SelectionStrategy]
(SelectionStrategy -> SelectionStrategy)
-> (SelectionStrategy -> SelectionStrategy)
-> (Int -> SelectionStrategy)
-> (SelectionStrategy -> Int)
-> (SelectionStrategy -> [SelectionStrategy])
-> (SelectionStrategy -> SelectionStrategy -> [SelectionStrategy])
-> (SelectionStrategy -> SelectionStrategy -> [SelectionStrategy])
-> (SelectionStrategy
-> SelectionStrategy -> SelectionStrategy -> [SelectionStrategy])
-> Enum SelectionStrategy
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: SelectionStrategy
-> SelectionStrategy -> SelectionStrategy -> [SelectionStrategy]
$cenumFromThenTo :: SelectionStrategy
-> SelectionStrategy -> SelectionStrategy -> [SelectionStrategy]
enumFromTo :: SelectionStrategy -> SelectionStrategy -> [SelectionStrategy]
$cenumFromTo :: SelectionStrategy -> SelectionStrategy -> [SelectionStrategy]
enumFromThen :: SelectionStrategy -> SelectionStrategy -> [SelectionStrategy]
$cenumFromThen :: SelectionStrategy -> SelectionStrategy -> [SelectionStrategy]
enumFrom :: SelectionStrategy -> [SelectionStrategy]
$cenumFrom :: SelectionStrategy -> [SelectionStrategy]
fromEnum :: SelectionStrategy -> Int
$cfromEnum :: SelectionStrategy -> Int
toEnum :: Int -> SelectionStrategy
$ctoEnum :: Int -> SelectionStrategy
pred :: SelectionStrategy -> SelectionStrategy
$cpred :: SelectionStrategy -> SelectionStrategy
succ :: SelectionStrategy -> SelectionStrategy
$csucc :: SelectionStrategy -> SelectionStrategy
Enum, SelectionStrategy -> SelectionStrategy -> Bool
(SelectionStrategy -> SelectionStrategy -> Bool)
-> (SelectionStrategy -> SelectionStrategy -> Bool)
-> Eq SelectionStrategy
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SelectionStrategy -> SelectionStrategy -> Bool
$c/= :: SelectionStrategy -> SelectionStrategy -> Bool
== :: SelectionStrategy -> SelectionStrategy -> Bool
$c== :: SelectionStrategy -> SelectionStrategy -> Bool
Eq, Int -> SelectionStrategy -> ShowS
[SelectionStrategy] -> ShowS
SelectionStrategy -> String
(Int -> SelectionStrategy -> ShowS)
-> (SelectionStrategy -> String)
-> ([SelectionStrategy] -> ShowS)
-> Show SelectionStrategy
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SelectionStrategy] -> ShowS
$cshowList :: [SelectionStrategy] -> ShowS
show :: SelectionStrategy -> String
$cshow :: SelectionStrategy -> String
showsPrec :: Int -> SelectionStrategy -> ShowS
$cshowsPrec :: Int -> SelectionStrategy -> ShowS
Show)
data UTxOBalanceSufficiency
= UTxOBalanceSufficient
| UTxOBalanceInsufficient
deriving (UTxOBalanceSufficiency -> UTxOBalanceSufficiency -> Bool
(UTxOBalanceSufficiency -> UTxOBalanceSufficiency -> Bool)
-> (UTxOBalanceSufficiency -> UTxOBalanceSufficiency -> Bool)
-> Eq UTxOBalanceSufficiency
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UTxOBalanceSufficiency -> UTxOBalanceSufficiency -> Bool
$c/= :: UTxOBalanceSufficiency -> UTxOBalanceSufficiency -> Bool
== :: UTxOBalanceSufficiency -> UTxOBalanceSufficiency -> Bool
$c== :: UTxOBalanceSufficiency -> UTxOBalanceSufficiency -> Bool
Eq, Int -> UTxOBalanceSufficiency -> ShowS
[UTxOBalanceSufficiency] -> ShowS
UTxOBalanceSufficiency -> String
(Int -> UTxOBalanceSufficiency -> ShowS)
-> (UTxOBalanceSufficiency -> String)
-> ([UTxOBalanceSufficiency] -> ShowS)
-> Show UTxOBalanceSufficiency
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UTxOBalanceSufficiency] -> ShowS
$cshowList :: [UTxOBalanceSufficiency] -> ShowS
show :: UTxOBalanceSufficiency -> String
$cshow :: UTxOBalanceSufficiency -> String
showsPrec :: Int -> UTxOBalanceSufficiency -> ShowS
$cshowsPrec :: Int -> UTxOBalanceSufficiency -> ShowS
Show)
data UTxOBalanceSufficiencyInfo = UTxOBalanceSufficiencyInfo
{ UTxOBalanceSufficiencyInfo -> TokenBundle
available :: TokenBundle
, UTxOBalanceSufficiencyInfo -> TokenBundle
required :: TokenBundle
, UTxOBalanceSufficiencyInfo -> TokenBundle
difference :: TokenBundle
, UTxOBalanceSufficiencyInfo -> UTxOBalanceSufficiency
sufficiency :: UTxOBalanceSufficiency
}
deriving (UTxOBalanceSufficiencyInfo -> UTxOBalanceSufficiencyInfo -> Bool
(UTxOBalanceSufficiencyInfo -> UTxOBalanceSufficiencyInfo -> Bool)
-> (UTxOBalanceSufficiencyInfo
-> UTxOBalanceSufficiencyInfo -> Bool)
-> Eq UTxOBalanceSufficiencyInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UTxOBalanceSufficiencyInfo -> UTxOBalanceSufficiencyInfo -> Bool
$c/= :: UTxOBalanceSufficiencyInfo -> UTxOBalanceSufficiencyInfo -> Bool
== :: UTxOBalanceSufficiencyInfo -> UTxOBalanceSufficiencyInfo -> Bool
$c== :: UTxOBalanceSufficiencyInfo -> UTxOBalanceSufficiencyInfo -> Bool
Eq, (forall x.
UTxOBalanceSufficiencyInfo -> Rep UTxOBalanceSufficiencyInfo x)
-> (forall x.
Rep UTxOBalanceSufficiencyInfo x -> UTxOBalanceSufficiencyInfo)
-> Generic UTxOBalanceSufficiencyInfo
forall x.
Rep UTxOBalanceSufficiencyInfo x -> UTxOBalanceSufficiencyInfo
forall x.
UTxOBalanceSufficiencyInfo -> Rep UTxOBalanceSufficiencyInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x.
Rep UTxOBalanceSufficiencyInfo x -> UTxOBalanceSufficiencyInfo
$cfrom :: forall x.
UTxOBalanceSufficiencyInfo -> Rep UTxOBalanceSufficiencyInfo x
Generic, Int -> UTxOBalanceSufficiencyInfo -> ShowS
[UTxOBalanceSufficiencyInfo] -> ShowS
UTxOBalanceSufficiencyInfo -> String
(Int -> UTxOBalanceSufficiencyInfo -> ShowS)
-> (UTxOBalanceSufficiencyInfo -> String)
-> ([UTxOBalanceSufficiencyInfo] -> ShowS)
-> Show UTxOBalanceSufficiencyInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UTxOBalanceSufficiencyInfo] -> ShowS
$cshowList :: [UTxOBalanceSufficiencyInfo] -> ShowS
show :: UTxOBalanceSufficiencyInfo -> String
$cshow :: UTxOBalanceSufficiencyInfo -> String
showsPrec :: Int -> UTxOBalanceSufficiencyInfo -> ShowS
$cshowsPrec :: Int -> UTxOBalanceSufficiencyInfo -> ShowS
Show)
computeUTxOBalanceAvailable
:: SelectionParamsOf f ctx -> TokenBundle
computeUTxOBalanceAvailable :: SelectionParamsOf f ctx -> TokenBundle
computeUTxOBalanceAvailable =
UTxOSelection (UTxO ctx) -> TokenBundle
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> TokenBundle
UTxOSelection.availableBalance (UTxOSelection (UTxO ctx) -> TokenBundle)
-> (SelectionParamsOf f ctx -> UTxOSelection (UTxO ctx))
-> SelectionParamsOf f ctx
-> TokenBundle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((UTxOSelection (UTxO ctx)
-> Const (UTxOSelection (UTxO ctx)) (UTxOSelection (UTxO ctx)))
-> SelectionParamsOf f ctx
-> Const (UTxOSelection (UTxO ctx)) (SelectionParamsOf f ctx))
-> SelectionParamsOf f ctx -> UTxOSelection (UTxO ctx)
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"utxoAvailable"
((UTxOSelection (UTxO ctx)
-> Const (UTxOSelection (UTxO ctx)) (UTxOSelection (UTxO ctx)))
-> SelectionParamsOf f ctx
-> Const (UTxOSelection (UTxO ctx)) (SelectionParamsOf f ctx))
(UTxOSelection (UTxO ctx)
-> Const (UTxOSelection (UTxO ctx)) (UTxOSelection (UTxO ctx)))
-> SelectionParamsOf f ctx
-> Const (UTxOSelection (UTxO ctx)) (SelectionParamsOf f ctx)
#utxoAvailable
computeUTxOBalanceRequired
:: Foldable f => SelectionParamsOf f ctx -> TokenBundle
computeUTxOBalanceRequired :: SelectionParamsOf f ctx -> TokenBundle
computeUTxOBalanceRequired = (TokenBundle, TokenBundle) -> TokenBundle
forall a b. (a, b) -> a
fst ((TokenBundle, TokenBundle) -> TokenBundle)
-> (SelectionParamsOf f ctx -> (TokenBundle, TokenBundle))
-> SelectionParamsOf f ctx
-> TokenBundle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SelectionParamsOf f ctx -> (TokenBundle, TokenBundle)
forall (f :: * -> *) ctx.
Foldable f =>
SelectionParamsOf f ctx -> (TokenBundle, TokenBundle)
computeDeficitInOut
computeBalanceInOut
:: Foldable f => SelectionParamsOf f ctx -> (TokenBundle, TokenBundle)
computeBalanceInOut :: SelectionParamsOf f ctx -> (TokenBundle, TokenBundle)
computeBalanceInOut SelectionParamsOf f ctx
params =
(TokenBundle
balanceIn, TokenBundle
balanceOut)
where
balanceIn :: TokenBundle
balanceIn =
TokenMap -> TokenBundle
TokenBundle.fromTokenMap (((TokenMap -> Const TokenMap TokenMap)
-> SelectionParamsOf f ctx
-> Const TokenMap (SelectionParamsOf f ctx))
-> SelectionParamsOf f ctx -> TokenMap
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"assetsToMint"
((TokenMap -> Const TokenMap TokenMap)
-> SelectionParamsOf f ctx
-> Const TokenMap (SelectionParamsOf f ctx))
(TokenMap -> Const TokenMap TokenMap)
-> SelectionParamsOf f ctx
-> Const TokenMap (SelectionParamsOf f ctx)
#assetsToMint SelectionParamsOf f ctx
params)
TokenBundle -> TokenBundle -> TokenBundle
`TokenBundle.add`
Coin -> TokenBundle
TokenBundle.fromCoin (((Coin -> Const Coin Coin)
-> SelectionParamsOf f ctx -> Const Coin (SelectionParamsOf f ctx))
-> SelectionParamsOf f ctx -> Coin
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"extraCoinSource"
((Coin -> Const Coin Coin)
-> SelectionParamsOf f ctx -> Const Coin (SelectionParamsOf f ctx))
(Coin -> Const Coin Coin)
-> SelectionParamsOf f ctx -> Const Coin (SelectionParamsOf f ctx)
#extraCoinSource SelectionParamsOf f ctx
params)
balanceOut :: TokenBundle
balanceOut =
TokenMap -> TokenBundle
TokenBundle.fromTokenMap (((TokenMap -> Const TokenMap TokenMap)
-> SelectionParamsOf f ctx
-> Const TokenMap (SelectionParamsOf f ctx))
-> SelectionParamsOf f ctx -> TokenMap
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"assetsToBurn"
((TokenMap -> Const TokenMap TokenMap)
-> SelectionParamsOf f ctx
-> Const TokenMap (SelectionParamsOf f ctx))
(TokenMap -> Const TokenMap TokenMap)
-> SelectionParamsOf f ctx
-> Const TokenMap (SelectionParamsOf f ctx)
#assetsToBurn SelectionParamsOf f ctx
params)
TokenBundle -> TokenBundle -> TokenBundle
`TokenBundle.add`
Coin -> TokenBundle
TokenBundle.fromCoin (((Coin -> Const Coin Coin)
-> SelectionParamsOf f ctx -> Const Coin (SelectionParamsOf f ctx))
-> SelectionParamsOf f ctx -> Coin
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"extraCoinSink"
((Coin -> Const Coin Coin)
-> SelectionParamsOf f ctx -> Const Coin (SelectionParamsOf f ctx))
(Coin -> Const Coin Coin)
-> SelectionParamsOf f ctx -> Const Coin (SelectionParamsOf f ctx)
#extraCoinSink SelectionParamsOf f ctx
params)
TokenBundle -> TokenBundle -> TokenBundle
`TokenBundle.add`
((Address ctx, TokenBundle) -> TokenBundle)
-> f (Address ctx, TokenBundle) -> TokenBundle
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
F.foldMap (Address ctx, TokenBundle) -> TokenBundle
forall a b. (a, b) -> b
snd (((f (Address ctx, TokenBundle)
-> Const
(f (Address ctx, TokenBundle)) (f (Address ctx, TokenBundle)))
-> SelectionParamsOf f ctx
-> Const (f (Address ctx, TokenBundle)) (SelectionParamsOf f ctx))
-> SelectionParamsOf f ctx -> f (Address ctx, TokenBundle)
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"outputsToCover"
((f (Address ctx, TokenBundle)
-> Const
(f (Address ctx, TokenBundle)) (f (Address ctx, TokenBundle)))
-> SelectionParamsOf f ctx
-> Const (f (Address ctx, TokenBundle)) (SelectionParamsOf f ctx))
(f (Address ctx, TokenBundle)
-> Const
(f (Address ctx, TokenBundle)) (f (Address ctx, TokenBundle)))
-> SelectionParamsOf f ctx
-> Const (f (Address ctx, TokenBundle)) (SelectionParamsOf f ctx)
#outputsToCover SelectionParamsOf f ctx
params)
computeDeficitInOut
:: Foldable f => SelectionParamsOf f ctx -> (TokenBundle, TokenBundle)
computeDeficitInOut :: SelectionParamsOf f ctx -> (TokenBundle, TokenBundle)
computeDeficitInOut SelectionParamsOf f ctx
params =
(TokenBundle
deficitIn, TokenBundle
deficitOut)
where
deficitIn :: TokenBundle
deficitIn =
TokenBundle -> TokenBundle -> TokenBundle
TokenBundle.difference TokenBundle
balanceOut TokenBundle
balanceIn
deficitOut :: TokenBundle
deficitOut =
TokenBundle -> TokenBundle -> TokenBundle
TokenBundle.difference TokenBundle
balanceIn TokenBundle
balanceOut
(TokenBundle
balanceIn, TokenBundle
balanceOut) =
SelectionParamsOf f ctx -> (TokenBundle, TokenBundle)
forall (f :: * -> *) ctx.
Foldable f =>
SelectionParamsOf f ctx -> (TokenBundle, TokenBundle)
computeBalanceInOut SelectionParamsOf f ctx
params
computeUTxOBalanceSufficiency
:: Foldable f => SelectionParamsOf f ctx -> UTxOBalanceSufficiency
computeUTxOBalanceSufficiency :: SelectionParamsOf f ctx -> UTxOBalanceSufficiency
computeUTxOBalanceSufficiency = UTxOBalanceSufficiencyInfo -> UTxOBalanceSufficiency
sufficiency (UTxOBalanceSufficiencyInfo -> UTxOBalanceSufficiency)
-> (SelectionParamsOf f ctx -> UTxOBalanceSufficiencyInfo)
-> SelectionParamsOf f ctx
-> UTxOBalanceSufficiency
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SelectionParamsOf f ctx -> UTxOBalanceSufficiencyInfo
forall (f :: * -> *) ctx.
Foldable f =>
SelectionParamsOf f ctx -> UTxOBalanceSufficiencyInfo
computeUTxOBalanceSufficiencyInfo
computeUTxOBalanceSufficiencyInfo
:: Foldable f => SelectionParamsOf f ctx -> UTxOBalanceSufficiencyInfo
computeUTxOBalanceSufficiencyInfo :: SelectionParamsOf f ctx -> UTxOBalanceSufficiencyInfo
computeUTxOBalanceSufficiencyInfo SelectionParamsOf f ctx
params =
UTxOBalanceSufficiencyInfo :: TokenBundle
-> TokenBundle
-> TokenBundle
-> UTxOBalanceSufficiency
-> UTxOBalanceSufficiencyInfo
UTxOBalanceSufficiencyInfo {TokenBundle
available :: TokenBundle
$sel:available:UTxOBalanceSufficiencyInfo :: TokenBundle
available, TokenBundle
required :: TokenBundle
$sel:required:UTxOBalanceSufficiencyInfo :: TokenBundle
required, TokenBundle
difference :: TokenBundle
$sel:difference:UTxOBalanceSufficiencyInfo :: TokenBundle
difference, UTxOBalanceSufficiency
sufficiency :: UTxOBalanceSufficiency
$sel:sufficiency:UTxOBalanceSufficiencyInfo :: UTxOBalanceSufficiency
sufficiency}
where
available :: TokenBundle
available = SelectionParamsOf f ctx -> TokenBundle
forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> TokenBundle
computeUTxOBalanceAvailable SelectionParamsOf f ctx
params
required :: TokenBundle
required = SelectionParamsOf f ctx -> TokenBundle
forall (f :: * -> *) ctx.
Foldable f =>
SelectionParamsOf f ctx -> TokenBundle
computeUTxOBalanceRequired SelectionParamsOf f ctx
params
sufficiency :: UTxOBalanceSufficiency
sufficiency =
if TokenBundle
required TokenBundle -> TokenBundle -> Bool
forall a. PartialOrd a => a -> a -> Bool
`leq` TokenBundle
available
then UTxOBalanceSufficiency
UTxOBalanceSufficient
else UTxOBalanceSufficiency
UTxOBalanceInsufficient
difference :: TokenBundle
difference =
if UTxOBalanceSufficiency
sufficiency UTxOBalanceSufficiency -> UTxOBalanceSufficiency -> Bool
forall a. Eq a => a -> a -> Bool
== UTxOBalanceSufficiency
UTxOBalanceSufficient
then TokenBundle -> TokenBundle -> TokenBundle
TokenBundle.difference TokenBundle
available TokenBundle
required
else TokenBundle -> TokenBundle -> TokenBundle
TokenBundle.difference TokenBundle
required TokenBundle
available
isUTxOBalanceSufficient
:: Foldable f => SelectionParamsOf f ctx -> Bool
isUTxOBalanceSufficient :: SelectionParamsOf f ctx -> Bool
isUTxOBalanceSufficient SelectionParamsOf f ctx
params =
case SelectionParamsOf f ctx -> UTxOBalanceSufficiency
forall (f :: * -> *) ctx.
Foldable f =>
SelectionParamsOf f ctx -> UTxOBalanceSufficiency
computeUTxOBalanceSufficiency SelectionParamsOf f ctx
params of
UTxOBalanceSufficiency
UTxOBalanceSufficient -> Bool
True
UTxOBalanceSufficiency
UTxOBalanceInsufficient -> Bool
False
data SelectionSkeleton ctx = SelectionSkeleton
{ SelectionSkeleton ctx -> Int
skeletonInputCount
:: !Int
, SelectionSkeleton ctx -> [(Address ctx, TokenBundle)]
skeletonOutputs
:: ![(Address ctx, TokenBundle)]
, SelectionSkeleton ctx -> [Set AssetId]
skeletonChange
:: ![Set AssetId]
}
deriving (forall x. SelectionSkeleton ctx -> Rep (SelectionSkeleton ctx) x)
-> (forall x.
Rep (SelectionSkeleton ctx) x -> SelectionSkeleton ctx)
-> Generic (SelectionSkeleton ctx)
forall x. Rep (SelectionSkeleton ctx) x -> SelectionSkeleton ctx
forall x. SelectionSkeleton ctx -> Rep (SelectionSkeleton ctx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall ctx x.
Rep (SelectionSkeleton ctx) x -> SelectionSkeleton ctx
forall ctx x.
SelectionSkeleton ctx -> Rep (SelectionSkeleton ctx) x
$cto :: forall ctx x.
Rep (SelectionSkeleton ctx) x -> SelectionSkeleton ctx
$cfrom :: forall ctx x.
SelectionSkeleton ctx -> Rep (SelectionSkeleton ctx) x
Generic
deriving instance SelectionContext ctx => Eq (SelectionSkeleton ctx)
deriving instance SelectionContext ctx => Show (SelectionSkeleton ctx)
type SelectionLimit = SelectionLimitOf Int
data SelectionLimitOf a
= NoLimit
| MaximumInputLimit a
deriving (SelectionLimitOf a -> SelectionLimitOf a -> Bool
(SelectionLimitOf a -> SelectionLimitOf a -> Bool)
-> (SelectionLimitOf a -> SelectionLimitOf a -> Bool)
-> Eq (SelectionLimitOf a)
forall a. Eq a => SelectionLimitOf a -> SelectionLimitOf a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SelectionLimitOf a -> SelectionLimitOf a -> Bool
$c/= :: forall a. Eq a => SelectionLimitOf a -> SelectionLimitOf a -> Bool
== :: SelectionLimitOf a -> SelectionLimitOf a -> Bool
$c== :: forall a. Eq a => SelectionLimitOf a -> SelectionLimitOf a -> Bool
Eq, a -> SelectionLimitOf b -> SelectionLimitOf a
(a -> b) -> SelectionLimitOf a -> SelectionLimitOf b
(forall a b. (a -> b) -> SelectionLimitOf a -> SelectionLimitOf b)
-> (forall a b. a -> SelectionLimitOf b -> SelectionLimitOf a)
-> Functor SelectionLimitOf
forall a b. a -> SelectionLimitOf b -> SelectionLimitOf a
forall a b. (a -> b) -> SelectionLimitOf a -> SelectionLimitOf b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SelectionLimitOf b -> SelectionLimitOf a
$c<$ :: forall a b. a -> SelectionLimitOf b -> SelectionLimitOf a
fmap :: (a -> b) -> SelectionLimitOf a -> SelectionLimitOf b
$cfmap :: forall a b. (a -> b) -> SelectionLimitOf a -> SelectionLimitOf b
Functor, Int -> SelectionLimitOf a -> ShowS
[SelectionLimitOf a] -> ShowS
SelectionLimitOf a -> String
(Int -> SelectionLimitOf a -> ShowS)
-> (SelectionLimitOf a -> String)
-> ([SelectionLimitOf a] -> ShowS)
-> Show (SelectionLimitOf a)
forall a. Show a => Int -> SelectionLimitOf a -> ShowS
forall a. Show a => [SelectionLimitOf a] -> ShowS
forall a. Show a => SelectionLimitOf a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SelectionLimitOf a] -> ShowS
$cshowList :: forall a. Show a => [SelectionLimitOf a] -> ShowS
show :: SelectionLimitOf a -> String
$cshow :: forall a. Show a => SelectionLimitOf a -> String
showsPrec :: Int -> SelectionLimitOf a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> SelectionLimitOf a -> ShowS
Show)
instance Ord a => Ord (SelectionLimitOf a) where
compare :: SelectionLimitOf a -> SelectionLimitOf a -> Ordering
compare SelectionLimitOf a
a SelectionLimitOf a
b = case (SelectionLimitOf a
a, SelectionLimitOf a
b) of
(SelectionLimitOf a
NoLimit , SelectionLimitOf a
NoLimit ) -> Ordering
EQ
(MaximumInputLimit a
_, SelectionLimitOf a
NoLimit ) -> Ordering
LT
(SelectionLimitOf a
NoLimit , MaximumInputLimit a
_) -> Ordering
GT
(MaximumInputLimit a
x, MaximumInputLimit a
y) -> a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y
selectionLimitExceeded :: IsUTxOSelection s u => s u -> SelectionLimit -> Bool
selectionLimitExceeded :: s u -> SelectionLimit -> Bool
selectionLimitExceeded s u
s = \case
SelectionLimit
NoLimit -> Bool
False
MaximumInputLimit Int
n -> s u -> Int
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> Int
UTxOSelection.selectedSize s u
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n
reduceSelectionLimitBy :: SelectionLimit -> Int -> SelectionLimit
reduceSelectionLimitBy :: SelectionLimit -> Int -> SelectionLimit
reduceSelectionLimitBy SelectionLimit
limit Int
reduction
| Int
reduction Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 =
SelectionLimit
limit
| Bool
otherwise =
Int -> Int -> Int
forall a. Num a => a -> a -> a
subtract Int
reduction (Int -> Int) -> SelectionLimit -> SelectionLimit
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SelectionLimit
limit
type SelectionResult = SelectionResultOf []
data SelectionResultOf f ctx = SelectionResult
{ SelectionResultOf f ctx -> NonEmpty (UTxO ctx, TokenBundle)
inputsSelected
:: !(NonEmpty (UTxO ctx, TokenBundle))
,
:: !Coin
,
:: !Coin
, SelectionResultOf f ctx -> f (Address ctx, TokenBundle)
outputsCovered
:: !(f (Address ctx, TokenBundle))
, SelectionResultOf f ctx -> [TokenBundle]
changeGenerated
:: ![TokenBundle]
, SelectionResultOf f ctx -> TokenMap
assetsToMint
:: !TokenMap
, SelectionResultOf f ctx -> TokenMap
assetsToBurn
:: !TokenMap
}
deriving (forall x.
SelectionResultOf f ctx -> Rep (SelectionResultOf f ctx) x)
-> (forall x.
Rep (SelectionResultOf f ctx) x -> SelectionResultOf f ctx)
-> Generic (SelectionResultOf f ctx)
forall x.
Rep (SelectionResultOf f ctx) x -> SelectionResultOf f ctx
forall x.
SelectionResultOf f ctx -> Rep (SelectionResultOf f ctx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (f :: * -> *) ctx x.
Rep (SelectionResultOf f ctx) x -> SelectionResultOf f ctx
forall (f :: * -> *) ctx x.
SelectionResultOf f ctx -> Rep (SelectionResultOf f ctx) x
$cto :: forall (f :: * -> *) ctx x.
Rep (SelectionResultOf f ctx) x -> SelectionResultOf f ctx
$cfrom :: forall (f :: * -> *) ctx x.
SelectionResultOf f ctx -> Rep (SelectionResultOf f ctx) x
Generic
deriving instance
(Eq (f (Address ctx, TokenBundle)), Eq (UTxO ctx)) =>
Eq (SelectionResultOf f ctx)
deriving instance
(Show (f (Address ctx, TokenBundle)), Show (UTxO ctx)) =>
Show (SelectionResultOf f ctx)
data SelectionDelta a
= SelectionSurplus a
| SelectionDeficit a
deriving (SelectionDelta a -> SelectionDelta a -> Bool
(SelectionDelta a -> SelectionDelta a -> Bool)
-> (SelectionDelta a -> SelectionDelta a -> Bool)
-> Eq (SelectionDelta a)
forall a. Eq a => SelectionDelta a -> SelectionDelta a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SelectionDelta a -> SelectionDelta a -> Bool
$c/= :: forall a. Eq a => SelectionDelta a -> SelectionDelta a -> Bool
== :: SelectionDelta a -> SelectionDelta a -> Bool
$c== :: forall a. Eq a => SelectionDelta a -> SelectionDelta a -> Bool
Eq, a -> SelectionDelta b -> SelectionDelta a
(a -> b) -> SelectionDelta a -> SelectionDelta b
(forall a b. (a -> b) -> SelectionDelta a -> SelectionDelta b)
-> (forall a b. a -> SelectionDelta b -> SelectionDelta a)
-> Functor SelectionDelta
forall a b. a -> SelectionDelta b -> SelectionDelta a
forall a b. (a -> b) -> SelectionDelta a -> SelectionDelta b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SelectionDelta b -> SelectionDelta a
$c<$ :: forall a b. a -> SelectionDelta b -> SelectionDelta a
fmap :: (a -> b) -> SelectionDelta a -> SelectionDelta b
$cfmap :: forall a b. (a -> b) -> SelectionDelta a -> SelectionDelta b
Functor, Int -> SelectionDelta a -> ShowS
[SelectionDelta a] -> ShowS
SelectionDelta a -> String
(Int -> SelectionDelta a -> ShowS)
-> (SelectionDelta a -> String)
-> ([SelectionDelta a] -> ShowS)
-> Show (SelectionDelta a)
forall a. Show a => Int -> SelectionDelta a -> ShowS
forall a. Show a => [SelectionDelta a] -> ShowS
forall a. Show a => SelectionDelta a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SelectionDelta a] -> ShowS
$cshowList :: forall a. Show a => [SelectionDelta a] -> ShowS
show :: SelectionDelta a -> String
$cshow :: forall a. Show a => SelectionDelta a -> String
showsPrec :: Int -> SelectionDelta a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> SelectionDelta a -> ShowS
Show)
instance Buildable a => Buildable (SelectionDelta a) where
build :: SelectionDelta a -> Builder
build SelectionDelta a
d = case SelectionDelta a
d of
SelectionSurplus a
surplus -> [(String, Builder)] -> Builder
buildMap [(String
"surplus", a -> Builder
forall p. Buildable p => p -> Builder
build a
surplus)]
SelectionDeficit a
deficit -> [(String, Builder)] -> Builder
buildMap [(String
"deficit", a -> Builder
forall p. Buildable p => p -> Builder
build a
deficit)]
where
buildMap :: [(String, Builder)] -> Builder
buildMap :: [(String, Builder)] -> Builder
buildMap = [(String, Builder)] -> Builder
forall t k v.
(IsList t, Item t ~ (k, v), Buildable k, Buildable v) =>
t -> Builder
blockMapF ([(String, Builder)] -> Builder)
-> ([(String, Builder)] -> [(String, Builder)])
-> [(String, Builder)]
-> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Builder) -> (String, Builder))
-> [(String, Builder)] -> [(String, Builder)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ShowS -> (String, Builder) -> (String, Builder)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ShowS -> (String, Builder) -> (String, Builder))
-> ShowS -> (String, Builder) -> (String, Builder)
forall a b. (a -> b) -> a -> b
$ ShowS
forall a. a -> a
id @String)
selectionDeltaAllAssets
:: Foldable f => SelectionResultOf f ctx -> SelectionDelta TokenBundle
selectionDeltaAllAssets :: SelectionResultOf f ctx -> SelectionDelta TokenBundle
selectionDeltaAllAssets SelectionResultOf f ctx
result
| TokenBundle
balanceOut TokenBundle -> TokenBundle -> Bool
forall a. PartialOrd a => a -> a -> Bool
`leq` TokenBundle
balanceIn =
TokenBundle -> SelectionDelta TokenBundle
forall a. a -> SelectionDelta a
SelectionSurplus (TokenBundle -> SelectionDelta TokenBundle)
-> TokenBundle -> SelectionDelta TokenBundle
forall a b. (a -> b) -> a -> b
$ TokenBundle -> TokenBundle -> TokenBundle
TokenBundle.difference TokenBundle
balanceIn TokenBundle
balanceOut
| Bool
otherwise =
TokenBundle -> SelectionDelta TokenBundle
forall a. a -> SelectionDelta a
SelectionDeficit (TokenBundle -> SelectionDelta TokenBundle)
-> TokenBundle -> SelectionDelta TokenBundle
forall a b. (a -> b) -> a -> b
$ TokenBundle -> TokenBundle -> TokenBundle
TokenBundle.difference TokenBundle
balanceOut TokenBundle
balanceIn
where
balanceIn :: TokenBundle
balanceIn =
TokenMap -> TokenBundle
TokenBundle.fromTokenMap TokenMap
assetsToMint
TokenBundle -> TokenBundle -> TokenBundle
`TokenBundle.add`
Coin -> TokenBundle
TokenBundle.fromCoin Coin
extraCoinSource
TokenBundle -> TokenBundle -> TokenBundle
`TokenBundle.add`
((UTxO ctx, TokenBundle) -> TokenBundle)
-> NonEmpty (UTxO ctx, TokenBundle) -> TokenBundle
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
F.foldMap (UTxO ctx, TokenBundle) -> TokenBundle
forall a b. (a, b) -> b
snd NonEmpty (UTxO ctx, TokenBundle)
inputsSelected
balanceOut :: TokenBundle
balanceOut =
TokenMap -> TokenBundle
TokenBundle.fromTokenMap TokenMap
assetsToBurn
TokenBundle -> TokenBundle -> TokenBundle
`TokenBundle.add`
Coin -> TokenBundle
TokenBundle.fromCoin Coin
extraCoinSink
TokenBundle -> TokenBundle -> TokenBundle
`TokenBundle.add`
((Address ctx, TokenBundle) -> TokenBundle)
-> f (Address ctx, TokenBundle) -> TokenBundle
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
F.foldMap (Address ctx, TokenBundle) -> TokenBundle
forall a b. (a, b) -> b
snd f (Address ctx, TokenBundle)
outputsCovered
TokenBundle -> TokenBundle -> TokenBundle
`TokenBundle.add`
[TokenBundle] -> TokenBundle
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
F.fold [TokenBundle]
changeGenerated
SelectionResult
{ TokenMap
assetsToMint :: TokenMap
$sel:assetsToMint:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> TokenMap
assetsToMint
, TokenMap
assetsToBurn :: TokenMap
$sel:assetsToBurn:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> TokenMap
assetsToBurn
, Coin
extraCoinSource :: Coin
$sel:extraCoinSource:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> Coin
extraCoinSource
, Coin
extraCoinSink :: Coin
$sel:extraCoinSink:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> Coin
extraCoinSink
, NonEmpty (UTxO ctx, TokenBundle)
inputsSelected :: NonEmpty (UTxO ctx, TokenBundle)
$sel:inputsSelected:SelectionResult :: forall (f :: * -> *) ctx.
SelectionResultOf f ctx -> NonEmpty (UTxO ctx, TokenBundle)
inputsSelected
, f (Address ctx, TokenBundle)
outputsCovered :: f (Address ctx, TokenBundle)
$sel:outputsCovered:SelectionResult :: forall (f :: * -> *) ctx.
SelectionResultOf f ctx -> f (Address ctx, TokenBundle)
outputsCovered
, [TokenBundle]
changeGenerated :: [TokenBundle]
$sel:changeGenerated:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> [TokenBundle]
changeGenerated
} = SelectionResultOf f ctx
result
selectionDeltaCoin
:: Foldable f => SelectionResultOf f ctx -> SelectionDelta Coin
selectionDeltaCoin :: SelectionResultOf f ctx -> SelectionDelta Coin
selectionDeltaCoin = (TokenBundle -> Coin)
-> SelectionDelta TokenBundle -> SelectionDelta Coin
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TokenBundle -> Coin
TokenBundle.getCoin (SelectionDelta TokenBundle -> SelectionDelta Coin)
-> (SelectionResultOf f ctx -> SelectionDelta TokenBundle)
-> SelectionResultOf f ctx
-> SelectionDelta Coin
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SelectionResultOf f ctx -> SelectionDelta TokenBundle
forall (f :: * -> *) ctx.
Foldable f =>
SelectionResultOf f ctx -> SelectionDelta TokenBundle
selectionDeltaAllAssets
selectionHasValidSurplus
:: Foldable f => SelectionConstraints ctx -> SelectionResultOf f ctx -> Bool
selectionHasValidSurplus :: SelectionConstraints ctx -> SelectionResultOf f ctx -> Bool
selectionHasValidSurplus SelectionConstraints ctx
constraints SelectionResultOf f ctx
selection =
case SelectionResultOf f ctx -> SelectionDelta TokenBundle
forall (f :: * -> *) ctx.
Foldable f =>
SelectionResultOf f ctx -> SelectionDelta TokenBundle
selectionDeltaAllAssets SelectionResultOf f ctx
selection of
SelectionSurplus TokenBundle
s -> TokenBundle -> Bool
surplusIsValid TokenBundle
s
SelectionDeficit TokenBundle
_ -> Bool
False
where
surplusIsValid :: TokenBundle -> Bool
surplusIsValid :: TokenBundle -> Bool
surplusIsValid = [TokenBundle -> Bool] -> TokenBundle -> Bool
forall (m :: * -> *). Monad m => [m Bool] -> m Bool
andM
[ Item [TokenBundle -> Bool]
TokenBundle -> Bool
surplusHasNoNonAdaAssets
, Item [TokenBundle -> Bool]
TokenBundle -> Bool
surplusNotBelowMinimumCost
, Item [TokenBundle -> Bool]
TokenBundle -> Bool
surplusNotAboveMaximumCost
]
surplusHasNoNonAdaAssets :: TokenBundle -> Bool
surplusHasNoNonAdaAssets :: TokenBundle -> Bool
surplusHasNoNonAdaAssets TokenBundle
surplus =
((TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle)
-> TokenBundle -> TokenMap
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"tokens"
((TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle)
(TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle
#tokens TokenBundle
surplus TokenMap -> TokenMap -> Bool
forall a. Eq a => a -> a -> Bool
== TokenMap
TokenMap.empty
surplusNotBelowMinimumCost :: TokenBundle -> Bool
surplusNotBelowMinimumCost :: TokenBundle -> Bool
surplusNotBelowMinimumCost TokenBundle
surplus =
((Coin -> Const Coin Coin)
-> TokenBundle -> Const Coin TokenBundle)
-> TokenBundle -> Coin
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"coin"
((Coin -> Const Coin Coin)
-> TokenBundle -> Const Coin TokenBundle)
(Coin -> Const Coin Coin) -> TokenBundle -> Const Coin TokenBundle
#coin TokenBundle
surplus Coin -> Coin -> Bool
forall a. Ord a => a -> a -> Bool
>= SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
forall (f :: * -> *) ctx.
Foldable f =>
SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
selectionMinimumCost SelectionConstraints ctx
constraints SelectionResultOf f ctx
selection
surplusNotAboveMaximumCost :: TokenBundle -> Bool
surplusNotAboveMaximumCost :: TokenBundle -> Bool
surplusNotAboveMaximumCost TokenBundle
surplus =
((Coin -> Const Coin Coin)
-> TokenBundle -> Const Coin TokenBundle)
-> TokenBundle -> Coin
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"coin"
((Coin -> Const Coin Coin)
-> TokenBundle -> Const Coin TokenBundle)
(Coin -> Const Coin Coin) -> TokenBundle -> Const Coin TokenBundle
#coin TokenBundle
surplus Coin -> Coin -> Bool
forall a. Ord a => a -> a -> Bool
<= SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
forall (f :: * -> *) ctx.
Foldable f =>
SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
selectionMaximumCost SelectionConstraints ctx
constraints SelectionResultOf f ctx
selection
selectionSurplusCoin :: Foldable f => SelectionResultOf f ctx -> Coin
selectionSurplusCoin :: SelectionResultOf f ctx -> Coin
selectionSurplusCoin SelectionResultOf f ctx
result =
case SelectionResultOf f ctx -> SelectionDelta Coin
forall (f :: * -> *) ctx.
Foldable f =>
SelectionResultOf f ctx -> SelectionDelta Coin
selectionDeltaCoin SelectionResultOf f ctx
result of
SelectionSurplus Coin
surplus -> Coin
surplus
SelectionDeficit Coin
_ -> Natural -> Coin
Coin Natural
0
selectionSkeleton
:: Foldable f => SelectionResultOf f ctx -> SelectionSkeleton ctx
selectionSkeleton :: SelectionResultOf f ctx -> SelectionSkeleton ctx
selectionSkeleton SelectionResultOf f ctx
s = SelectionSkeleton :: forall ctx.
Int
-> [(Address ctx, TokenBundle)]
-> [Set AssetId]
-> SelectionSkeleton ctx
SelectionSkeleton
{ $sel:skeletonInputCount:SelectionSkeleton :: Int
skeletonInputCount = NonEmpty (UTxO ctx, TokenBundle) -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
F.length (((NonEmpty (UTxO ctx, TokenBundle)
-> Const
(NonEmpty (UTxO ctx, TokenBundle))
(NonEmpty (UTxO ctx, TokenBundle)))
-> SelectionResultOf f ctx
-> Const
(NonEmpty (UTxO ctx, TokenBundle)) (SelectionResultOf f ctx))
-> SelectionResultOf f ctx -> NonEmpty (UTxO ctx, TokenBundle)
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"inputsSelected"
((NonEmpty (UTxO ctx, TokenBundle)
-> Const
(NonEmpty (UTxO ctx, TokenBundle))
(NonEmpty (UTxO ctx, TokenBundle)))
-> SelectionResultOf f ctx
-> Const
(NonEmpty (UTxO ctx, TokenBundle)) (SelectionResultOf f ctx))
(NonEmpty (UTxO ctx, TokenBundle)
-> Const
(NonEmpty (UTxO ctx, TokenBundle))
(NonEmpty (UTxO ctx, TokenBundle)))
-> SelectionResultOf f ctx
-> Const
(NonEmpty (UTxO ctx, TokenBundle)) (SelectionResultOf f ctx)
#inputsSelected SelectionResultOf f ctx
s)
, $sel:skeletonOutputs:SelectionSkeleton :: [(Address ctx, TokenBundle)]
skeletonOutputs = f (Address ctx, TokenBundle) -> [(Address ctx, TokenBundle)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList (((f (Address ctx, TokenBundle)
-> Const
(f (Address ctx, TokenBundle)) (f (Address ctx, TokenBundle)))
-> SelectionResultOf f ctx
-> Const (f (Address ctx, TokenBundle)) (SelectionResultOf f ctx))
-> SelectionResultOf f ctx -> f (Address ctx, TokenBundle)
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"outputsCovered"
((f (Address ctx, TokenBundle)
-> Const
(f (Address ctx, TokenBundle)) (f (Address ctx, TokenBundle)))
-> SelectionResultOf f ctx
-> Const (f (Address ctx, TokenBundle)) (SelectionResultOf f ctx))
(f (Address ctx, TokenBundle)
-> Const
(f (Address ctx, TokenBundle)) (f (Address ctx, TokenBundle)))
-> SelectionResultOf f ctx
-> Const (f (Address ctx, TokenBundle)) (SelectionResultOf f ctx)
#outputsCovered SelectionResultOf f ctx
s)
, $sel:skeletonChange:SelectionSkeleton :: [Set AssetId]
skeletonChange = TokenBundle -> Set AssetId
TokenBundle.getAssets (TokenBundle -> Set AssetId) -> [TokenBundle] -> [Set AssetId]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (([TokenBundle] -> Const [TokenBundle] [TokenBundle])
-> SelectionResultOf f ctx
-> Const [TokenBundle] (SelectionResultOf f ctx))
-> SelectionResultOf f ctx -> [TokenBundle]
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"changeGenerated"
(([TokenBundle] -> Const [TokenBundle] [TokenBundle])
-> SelectionResultOf f ctx
-> Const [TokenBundle] (SelectionResultOf f ctx))
([TokenBundle] -> Const [TokenBundle] [TokenBundle])
-> SelectionResultOf f ctx
-> Const [TokenBundle] (SelectionResultOf f ctx)
#changeGenerated SelectionResultOf f ctx
s
}
selectionMinimumCost
:: Foldable f => SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
selectionMinimumCost :: SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
selectionMinimumCost SelectionConstraints ctx
c = (((SelectionSkeleton ctx -> Coin)
-> Const
(SelectionSkeleton ctx -> Coin) (SelectionSkeleton ctx -> Coin))
-> SelectionConstraints ctx
-> Const
(SelectionSkeleton ctx -> Coin) (SelectionConstraints ctx))
-> SelectionConstraints ctx -> SelectionSkeleton ctx -> Coin
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"computeMinimumCost"
(((SelectionSkeleton ctx -> Coin)
-> Const
(SelectionSkeleton ctx -> Coin) (SelectionSkeleton ctx -> Coin))
-> SelectionConstraints ctx
-> Const
(SelectionSkeleton ctx -> Coin) (SelectionConstraints ctx))
((SelectionSkeleton ctx -> Coin)
-> Const
(SelectionSkeleton ctx -> Coin) (SelectionSkeleton ctx -> Coin))
-> SelectionConstraints ctx
-> Const (SelectionSkeleton ctx -> Coin) (SelectionConstraints ctx)
#computeMinimumCost SelectionConstraints ctx
c (SelectionSkeleton ctx -> Coin)
-> (SelectionResultOf f ctx -> SelectionSkeleton ctx)
-> SelectionResultOf f ctx
-> Coin
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SelectionResultOf f ctx -> SelectionSkeleton ctx
forall (f :: * -> *) ctx.
Foldable f =>
SelectionResultOf f ctx -> SelectionSkeleton ctx
selectionSkeleton
selectionMaximumCost
:: Foldable f => SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
selectionMaximumCost :: SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
selectionMaximumCost SelectionConstraints ctx
c = Int -> Coin -> Coin
forall b a. (Integral b, Monoid a) => b -> a -> a
mtimesDefault (Int
2 :: Int) (Coin -> Coin)
-> (SelectionResultOf f ctx -> Coin)
-> SelectionResultOf f ctx
-> Coin
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
forall (f :: * -> *) ctx.
Foldable f =>
SelectionConstraints ctx -> SelectionResultOf f ctx -> Coin
selectionMinimumCost SelectionConstraints ctx
c
data SelectionBalanceError ctx
= BalanceInsufficient
BalanceInsufficientError
| SelectionLimitReached
(SelectionLimitReachedError ctx)
| UnableToConstructChange
UnableToConstructChangeError
| EmptyUTxO
deriving (forall x.
SelectionBalanceError ctx -> Rep (SelectionBalanceError ctx) x)
-> (forall x.
Rep (SelectionBalanceError ctx) x -> SelectionBalanceError ctx)
-> Generic (SelectionBalanceError ctx)
forall x.
Rep (SelectionBalanceError ctx) x -> SelectionBalanceError ctx
forall x.
SelectionBalanceError ctx -> Rep (SelectionBalanceError ctx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall ctx x.
Rep (SelectionBalanceError ctx) x -> SelectionBalanceError ctx
forall ctx x.
SelectionBalanceError ctx -> Rep (SelectionBalanceError ctx) x
$cto :: forall ctx x.
Rep (SelectionBalanceError ctx) x -> SelectionBalanceError ctx
$cfrom :: forall ctx x.
SelectionBalanceError ctx -> Rep (SelectionBalanceError ctx) x
Generic
deriving instance SelectionContext ctx => Eq (SelectionBalanceError ctx)
deriving instance SelectionContext ctx => Show (SelectionBalanceError ctx)
data SelectionLimitReachedError ctx = SelectionLimitReachedError
{ SelectionLimitReachedError ctx -> TokenBundle
utxoBalanceRequired
:: !TokenBundle
, SelectionLimitReachedError ctx -> [(UTxO ctx, TokenBundle)]
inputsSelected
:: ![(UTxO ctx, TokenBundle)]
, SelectionLimitReachedError ctx
-> NonEmpty (Address ctx, TokenBundle)
outputsToCover
:: !(NonEmpty (Address ctx, TokenBundle))
} deriving (forall x.
SelectionLimitReachedError ctx
-> Rep (SelectionLimitReachedError ctx) x)
-> (forall x.
Rep (SelectionLimitReachedError ctx) x
-> SelectionLimitReachedError ctx)
-> Generic (SelectionLimitReachedError ctx)
forall x.
Rep (SelectionLimitReachedError ctx) x
-> SelectionLimitReachedError ctx
forall x.
SelectionLimitReachedError ctx
-> Rep (SelectionLimitReachedError ctx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall ctx x.
Rep (SelectionLimitReachedError ctx) x
-> SelectionLimitReachedError ctx
forall ctx x.
SelectionLimitReachedError ctx
-> Rep (SelectionLimitReachedError ctx) x
$cto :: forall ctx x.
Rep (SelectionLimitReachedError ctx) x
-> SelectionLimitReachedError ctx
$cfrom :: forall ctx x.
SelectionLimitReachedError ctx
-> Rep (SelectionLimitReachedError ctx) x
Generic
deriving instance SelectionContext ctx => Eq (SelectionLimitReachedError ctx)
deriving instance SelectionContext ctx => Show (SelectionLimitReachedError ctx)
data BalanceInsufficientError = BalanceInsufficientError
{ BalanceInsufficientError -> TokenBundle
utxoBalanceAvailable
:: !TokenBundle
, BalanceInsufficientError -> TokenBundle
utxoBalanceRequired
:: !TokenBundle
} deriving ((forall x.
BalanceInsufficientError -> Rep BalanceInsufficientError x)
-> (forall x.
Rep BalanceInsufficientError x -> BalanceInsufficientError)
-> Generic BalanceInsufficientError
forall x.
Rep BalanceInsufficientError x -> BalanceInsufficientError
forall x.
BalanceInsufficientError -> Rep BalanceInsufficientError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x.
Rep BalanceInsufficientError x -> BalanceInsufficientError
$cfrom :: forall x.
BalanceInsufficientError -> Rep BalanceInsufficientError x
Generic, BalanceInsufficientError -> BalanceInsufficientError -> Bool
(BalanceInsufficientError -> BalanceInsufficientError -> Bool)
-> (BalanceInsufficientError -> BalanceInsufficientError -> Bool)
-> Eq BalanceInsufficientError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BalanceInsufficientError -> BalanceInsufficientError -> Bool
$c/= :: BalanceInsufficientError -> BalanceInsufficientError -> Bool
== :: BalanceInsufficientError -> BalanceInsufficientError -> Bool
$c== :: BalanceInsufficientError -> BalanceInsufficientError -> Bool
Eq, Int -> BalanceInsufficientError -> ShowS
[BalanceInsufficientError] -> ShowS
BalanceInsufficientError -> String
(Int -> BalanceInsufficientError -> ShowS)
-> (BalanceInsufficientError -> String)
-> ([BalanceInsufficientError] -> ShowS)
-> Show BalanceInsufficientError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BalanceInsufficientError] -> ShowS
$cshowList :: [BalanceInsufficientError] -> ShowS
show :: BalanceInsufficientError -> String
$cshow :: BalanceInsufficientError -> String
showsPrec :: Int -> BalanceInsufficientError -> ShowS
$cshowsPrec :: Int -> BalanceInsufficientError -> ShowS
Show)
balanceMissing :: BalanceInsufficientError -> TokenBundle
balanceMissing :: BalanceInsufficientError -> TokenBundle
balanceMissing (BalanceInsufficientError TokenBundle
available TokenBundle
required) =
TokenBundle -> TokenBundle -> TokenBundle
TokenBundle.difference TokenBundle
required TokenBundle
available
data UnableToConstructChangeError = UnableToConstructChangeError
{ UnableToConstructChangeError -> Coin
requiredCost
:: !Coin
, UnableToConstructChangeError -> Coin
shortfall
:: !Coin
} deriving ((forall x.
UnableToConstructChangeError -> Rep UnableToConstructChangeError x)
-> (forall x.
Rep UnableToConstructChangeError x -> UnableToConstructChangeError)
-> Generic UnableToConstructChangeError
forall x.
Rep UnableToConstructChangeError x -> UnableToConstructChangeError
forall x.
UnableToConstructChangeError -> Rep UnableToConstructChangeError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x.
Rep UnableToConstructChangeError x -> UnableToConstructChangeError
$cfrom :: forall x.
UnableToConstructChangeError -> Rep UnableToConstructChangeError x
Generic, UnableToConstructChangeError
-> UnableToConstructChangeError -> Bool
(UnableToConstructChangeError
-> UnableToConstructChangeError -> Bool)
-> (UnableToConstructChangeError
-> UnableToConstructChangeError -> Bool)
-> Eq UnableToConstructChangeError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnableToConstructChangeError
-> UnableToConstructChangeError -> Bool
$c/= :: UnableToConstructChangeError
-> UnableToConstructChangeError -> Bool
== :: UnableToConstructChangeError
-> UnableToConstructChangeError -> Bool
$c== :: UnableToConstructChangeError
-> UnableToConstructChangeError -> Bool
Eq, Int -> UnableToConstructChangeError -> ShowS
[UnableToConstructChangeError] -> ShowS
UnableToConstructChangeError -> String
(Int -> UnableToConstructChangeError -> ShowS)
-> (UnableToConstructChangeError -> String)
-> ([UnableToConstructChangeError] -> ShowS)
-> Show UnableToConstructChangeError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UnableToConstructChangeError] -> ShowS
$cshowList :: [UnableToConstructChangeError] -> ShowS
show :: UnableToConstructChangeError -> String
$cshow :: UnableToConstructChangeError -> String
showsPrec :: Int -> UnableToConstructChangeError -> ShowS
$cshowsPrec :: Int -> UnableToConstructChangeError -> ShowS
Show)
type PerformSelection m f ctx =
SelectionConstraints ctx ->
SelectionParamsOf f ctx ->
m (Either (SelectionBalanceError ctx) (SelectionResultOf f ctx))
performSelection
:: forall m ctx. (HasCallStack, MonadRandom m, SelectionContext ctx)
=> PerformSelection m [] ctx
performSelection :: PerformSelection m [] ctx
performSelection = PerformSelection m NonEmpty ctx -> PerformSelection m [] ctx
forall (m :: * -> *) ctx.
Functor m =>
PerformSelection m NonEmpty ctx -> PerformSelection m [] ctx
performSelectionEmpty PerformSelection m NonEmpty ctx
forall (m :: * -> *) ctx.
(HasCallStack, MonadRandom m, SelectionContext ctx) =>
PerformSelection m NonEmpty ctx
performSelectionNonEmpty
performSelectionEmpty
:: forall m ctx. (Functor m)
=> PerformSelection m NonEmpty ctx
-> PerformSelection m [] ctx
performSelectionEmpty :: PerformSelection m NonEmpty ctx -> PerformSelection m [] ctx
performSelectionEmpty PerformSelection m NonEmpty ctx
performSelectionFn SelectionConstraints ctx
constraints SelectionParamsOf [] ctx
params =
(SelectionResultOf NonEmpty ctx -> SelectionResultOf [] ctx)
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> Either (SelectionBalanceError ctx) (SelectionResultOf [] ctx)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SelectionResultOf NonEmpty ctx -> SelectionResultOf [] ctx
transformResult (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> Either (SelectionBalanceError ctx) (SelectionResultOf [] ctx))
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf [] ctx))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
PerformSelection m NonEmpty ctx
performSelectionFn SelectionConstraints ctx
constraints (SelectionParamsOf [] ctx -> SelectionParamsOf NonEmpty ctx
transformParams SelectionParamsOf [] ctx
params)
where
transformParams
:: SelectionParamsOf [] ctx
-> SelectionParamsOf NonEmpty ctx
transformParams :: SelectionParamsOf [] ctx -> SelectionParamsOf NonEmpty ctx
transformParams p :: SelectionParamsOf [] ctx
p@SelectionParams {[(Address ctx, TokenBundle)]
TokenMap
Coin
UTxOSelection (UTxO ctx)
SelectionStrategy
selectionStrategy :: SelectionStrategy
assetsToBurn :: TokenMap
assetsToMint :: TokenMap
extraCoinSink :: Coin
extraCoinSource :: Coin
utxoAvailable :: UTxOSelection (UTxO ctx)
outputsToCover :: [(Address ctx, TokenBundle)]
$sel:selectionStrategy:SelectionParams :: forall (f :: * -> *) ctx.
SelectionParamsOf f ctx -> SelectionStrategy
$sel:assetsToBurn:SelectionParams :: forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> TokenMap
$sel:assetsToMint:SelectionParams :: forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> TokenMap
$sel:extraCoinSink:SelectionParams :: forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> Coin
$sel:extraCoinSource:SelectionParams :: forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> Coin
$sel:utxoAvailable:SelectionParams :: forall (f :: * -> *) ctx.
SelectionParamsOf f ctx -> UTxOSelection (UTxO ctx)
$sel:outputsToCover:SelectionParams :: forall (f :: * -> *) ctx.
SelectionParamsOf f ctx -> f (Address ctx, TokenBundle)
..} = SelectionParamsOf [] ctx
p
{ $sel:extraCoinSource:SelectionParams :: Coin
extraCoinSource =
(Coin -> Coin)
-> (NonEmpty (Address ctx, TokenBundle) -> Coin -> Coin)
-> Coin
-> Coin
forall a. a -> (NonEmpty (Address ctx, TokenBundle) -> a) -> a
transform (Coin -> Coin -> Coin
`Coin.add` Coin
dummyCoin) ((Coin -> Coin)
-> NonEmpty (Address ctx, TokenBundle) -> Coin -> Coin
forall a b. a -> b -> a
const Coin -> Coin
forall a. a -> a
id) Coin
extraCoinSource
, $sel:outputsToCover:SelectionParams :: NonEmpty (Address ctx, TokenBundle)
outputsToCover =
([(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle))
-> (NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle))
-> [(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle)
forall a. a -> (NonEmpty (Address ctx, TokenBundle) -> a) -> a
transform (NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle)
forall a b. a -> b -> a
const ((Address ctx, TokenBundle)
dummyOutput (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle)
forall a. a -> [a] -> NonEmpty a
:| [])) (NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle)
forall a b. a -> b -> a
const (NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle))
-> (NonEmpty (Address ctx, TokenBundle)
-> NonEmpty (Address ctx, TokenBundle))
-> NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (Address ctx, TokenBundle)
-> NonEmpty (Address ctx, TokenBundle)
forall a. a -> a
id) [(Address ctx, TokenBundle)]
outputsToCover
}
transformResult
:: SelectionResultOf NonEmpty ctx
-> SelectionResultOf [] ctx
transformResult :: SelectionResultOf NonEmpty ctx -> SelectionResultOf [] ctx
transformResult r :: SelectionResultOf NonEmpty ctx
r@SelectionResult {[TokenBundle]
NonEmpty (Address ctx, TokenBundle)
NonEmpty (UTxO ctx, TokenBundle)
TokenMap
Coin
assetsToBurn :: TokenMap
assetsToMint :: TokenMap
changeGenerated :: [TokenBundle]
outputsCovered :: NonEmpty (Address ctx, TokenBundle)
extraCoinSink :: Coin
extraCoinSource :: Coin
inputsSelected :: NonEmpty (UTxO ctx, TokenBundle)
$sel:assetsToBurn:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> TokenMap
$sel:assetsToMint:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> TokenMap
$sel:changeGenerated:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> [TokenBundle]
$sel:outputsCovered:SelectionResult :: forall (f :: * -> *) ctx.
SelectionResultOf f ctx -> f (Address ctx, TokenBundle)
$sel:extraCoinSink:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> Coin
$sel:extraCoinSource:SelectionResult :: forall (f :: * -> *) ctx. SelectionResultOf f ctx -> Coin
$sel:inputsSelected:SelectionResult :: forall (f :: * -> *) ctx.
SelectionResultOf f ctx -> NonEmpty (UTxO ctx, TokenBundle)
..} = SelectionResultOf NonEmpty ctx
r
{ $sel:extraCoinSource:SelectionResult :: Coin
extraCoinSource =
(Coin -> Coin)
-> (NonEmpty (Address ctx, TokenBundle) -> Coin -> Coin)
-> Coin
-> Coin
forall a. a -> (NonEmpty (Address ctx, TokenBundle) -> a) -> a
transform (Coin -> Coin -> Coin
`Coin.difference` Coin
dummyCoin) ((Coin -> Coin)
-> NonEmpty (Address ctx, TokenBundle) -> Coin -> Coin
forall a b. a -> b -> a
const Coin -> Coin
forall a. a -> a
id) Coin
extraCoinSource
, $sel:outputsCovered:SelectionResult :: [(Address ctx, TokenBundle)]
outputsCovered =
(NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)])
-> (NonEmpty (Address ctx, TokenBundle)
-> NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)])
-> NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
forall a. a -> (NonEmpty (Address ctx, TokenBundle) -> a) -> a
transform ([(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
forall a b. a -> b -> a
const []) ([(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
forall a b. a -> b -> a
const ([(Address ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)])
-> (NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)])
-> NonEmpty (Address ctx, TokenBundle)
-> NonEmpty (Address ctx, TokenBundle)
-> [(Address ctx, TokenBundle)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (Address ctx, TokenBundle) -> [(Address ctx, TokenBundle)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList) NonEmpty (Address ctx, TokenBundle)
outputsCovered
}
transform :: a -> (NonEmpty (Address ctx, TokenBundle) -> a) -> a
transform :: a -> (NonEmpty (Address ctx, TokenBundle) -> a) -> a
transform a
x NonEmpty (Address ctx, TokenBundle) -> a
y = a
-> (NonEmpty (Address ctx, TokenBundle) -> a)
-> Maybe (NonEmpty (Address ctx, TokenBundle))
-> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
x NonEmpty (Address ctx, TokenBundle) -> a
y (Maybe (NonEmpty (Address ctx, TokenBundle)) -> a)
-> Maybe (NonEmpty (Address ctx, TokenBundle)) -> a
forall a b. (a -> b) -> a -> b
$ [(Address ctx, TokenBundle)]
-> Maybe (NonEmpty (Address ctx, TokenBundle))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty ([(Address ctx, TokenBundle)]
-> Maybe (NonEmpty (Address ctx, TokenBundle)))
-> [(Address ctx, TokenBundle)]
-> Maybe (NonEmpty (Address ctx, TokenBundle))
forall a b. (a -> b) -> a -> b
$ (([(Address ctx, TokenBundle)]
-> Const [(Address ctx, TokenBundle)] [(Address ctx, TokenBundle)])
-> SelectionParamsOf [] ctx
-> Const [(Address ctx, TokenBundle)] (SelectionParamsOf [] ctx))
-> SelectionParamsOf [] ctx -> [(Address ctx, TokenBundle)]
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"outputsToCover"
(([(Address ctx, TokenBundle)]
-> Const [(Address ctx, TokenBundle)] [(Address ctx, TokenBundle)])
-> SelectionParamsOf [] ctx
-> Const [(Address ctx, TokenBundle)] (SelectionParamsOf [] ctx))
([(Address ctx, TokenBundle)]
-> Const [(Address ctx, TokenBundle)] [(Address ctx, TokenBundle)])
-> SelectionParamsOf [] ctx
-> Const [(Address ctx, TokenBundle)] (SelectionParamsOf [] ctx)
#outputsToCover SelectionParamsOf [] ctx
params
dummyOutput :: (Address ctx, TokenBundle)
dummyOutput :: (Address ctx, TokenBundle)
dummyOutput = (Address ctx
dummyAddress, Coin -> TokenBundle
TokenBundle.fromCoin Coin
dummyCoin)
dummyAddress :: Address ctx
dummyAddress = SelectionConstraints ctx -> Address ctx
forall ctx. SelectionConstraints ctx -> Address ctx
nullAddress SelectionConstraints ctx
constraints
dummyCoin :: Coin
dummyCoin :: Coin
dummyCoin = Natural -> Coin
Coin Natural
1
performSelectionNonEmpty
:: forall m ctx. (HasCallStack, MonadRandom m, SelectionContext ctx)
=> PerformSelection m NonEmpty ctx
performSelectionNonEmpty :: PerformSelection m NonEmpty ctx
performSelectionNonEmpty SelectionConstraints ctx
constraints SelectionParamsOf NonEmpty ctx
params
| Bool -> Bool
not Bool
utxoBalanceSufficient =
Either (SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)))
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall a b. (a -> b) -> a -> b
$ SelectionBalanceError ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
forall a b. a -> Either a b
Left (SelectionBalanceError ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
-> SelectionBalanceError ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
forall a b. (a -> b) -> a -> b
$ BalanceInsufficientError -> SelectionBalanceError ctx
forall ctx. BalanceInsufficientError -> SelectionBalanceError ctx
BalanceInsufficient (BalanceInsufficientError -> SelectionBalanceError ctx)
-> BalanceInsufficientError -> SelectionBalanceError ctx
forall a b. (a -> b) -> a -> b
$ BalanceInsufficientError :: TokenBundle -> TokenBundle -> BalanceInsufficientError
BalanceInsufficientError
{TokenBundle
utxoBalanceAvailable :: TokenBundle
$sel:utxoBalanceAvailable:BalanceInsufficientError :: TokenBundle
utxoBalanceAvailable, TokenBundle
utxoBalanceRequired :: TokenBundle
$sel:utxoBalanceRequired:BalanceInsufficientError :: TokenBundle
utxoBalanceRequired}
| Bool
otherwise = do
Maybe (UTxOSelectionNonEmpty (UTxO ctx))
maybeSelection <- RunSelectionParams (UTxO ctx)
-> m (Maybe (UTxOSelectionNonEmpty (UTxO ctx)))
forall (m :: * -> *) u.
(MonadRandom m, Ord u) =>
RunSelectionParams u -> m (Maybe (UTxOSelectionNonEmpty u))
runSelectionNonEmpty RunSelectionParams :: forall u.
SelectionLimit
-> UTxOSelection u
-> TokenBundle
-> SelectionStrategy
-> RunSelectionParams u
RunSelectionParams
{ SelectionLimit
$sel:selectionLimit:RunSelectionParams :: SelectionLimit
selectionLimit :: SelectionLimit
selectionLimit
, UTxOSelection (UTxO ctx)
$sel:utxoAvailable:RunSelectionParams :: UTxOSelection (UTxO ctx)
utxoAvailable :: UTxOSelection (UTxO ctx)
utxoAvailable
, $sel:minimumBalance:RunSelectionParams :: TokenBundle
minimumBalance = TokenBundle
utxoBalanceRequired
, SelectionStrategy
$sel:selectionStrategy:RunSelectionParams :: SelectionStrategy
selectionStrategy :: SelectionStrategy
selectionStrategy
}
case Maybe (UTxOSelectionNonEmpty (UTxO ctx))
maybeSelection of
Maybe (UTxOSelectionNonEmpty (UTxO ctx))
Nothing | UTxOSelection (UTxO ctx)
utxoAvailable UTxOSelection (UTxO ctx) -> UTxOSelection (UTxO ctx) -> Bool
forall a. Eq a => a -> a -> Bool
== UTxOSelection (UTxO ctx)
forall u. UTxOSelection u
UTxOSelection.empty ->
Either (SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)))
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall a b. (a -> b) -> a -> b
$ SelectionBalanceError ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
forall a b. a -> Either a b
Left SelectionBalanceError ctx
forall ctx. SelectionBalanceError ctx
EmptyUTxO
Maybe (UTxOSelectionNonEmpty (UTxO ctx))
Nothing ->
[(UTxO ctx, TokenBundle)]
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall a.
[(UTxO ctx, TokenBundle)]
-> m (Either (SelectionBalanceError ctx) a)
selectionLimitReachedError []
Just UTxOSelectionNonEmpty (UTxO ctx)
selection | UTxOSelectionNonEmpty (UTxO ctx) -> SelectionLimit -> Bool
forall (s :: * -> *) u.
IsUTxOSelection s u =>
s u -> SelectionLimit -> Bool
selectionLimitExceeded UTxOSelectionNonEmpty (UTxO ctx)
selection SelectionLimit
selectionLimit ->
[(UTxO ctx, TokenBundle)]
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall a.
[(UTxO ctx, TokenBundle)]
-> m (Either (SelectionBalanceError ctx) a)
selectionLimitReachedError ([(UTxO ctx, TokenBundle)]
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)))
-> [(UTxO ctx, TokenBundle)]
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall a b. (a -> b) -> a -> b
$ NonEmpty (UTxO ctx, TokenBundle) -> [(UTxO ctx, TokenBundle)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList (NonEmpty (UTxO ctx, TokenBundle) -> [(UTxO ctx, TokenBundle)])
-> NonEmpty (UTxO ctx, TokenBundle) -> [(UTxO ctx, TokenBundle)]
forall a b. (a -> b) -> a -> b
$
UTxOSelectionNonEmpty (UTxO ctx)
-> SelectedList UTxOSelectionNonEmpty (UTxO ctx)
forall (s :: * -> *) u.
IsUTxOSelection s u =>
s u -> SelectedList s u
UTxOSelection.selectedList UTxOSelectionNonEmpty (UTxO ctx)
selection
Just UTxOSelectionNonEmpty (UTxO ctx)
selection -> do
let utxoSelected :: UTxOIndex (UTxO ctx)
utxoSelected = UTxOSelectionNonEmpty (UTxO ctx) -> UTxOIndex (UTxO ctx)
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> UTxOIndex u
UTxOSelection.selectedIndex UTxOSelectionNonEmpty (UTxO ctx)
selection
let utxoBalanceSelected :: TokenBundle
utxoBalanceSelected = UTxOIndex (UTxO ctx) -> TokenBundle
forall u. UTxOIndex u -> TokenBundle
UTxOIndex.balance UTxOIndex (UTxO ctx)
utxoSelected
if TokenBundle
utxoBalanceRequired TokenBundle -> TokenBundle -> Bool
forall a. PartialOrd a => a -> a -> Bool
`leq` TokenBundle
utxoBalanceSelected
then UTxOSelectionNonEmpty (UTxO ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
makeChangeRepeatedly UTxOSelectionNonEmpty (UTxO ctx)
selection
else [(UTxO ctx, TokenBundle)]
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall a.
[(UTxO ctx, TokenBundle)]
-> m (Either (SelectionBalanceError ctx) a)
selectionLimitReachedError (UTxOIndex (UTxO ctx) -> [(UTxO ctx, TokenBundle)]
forall u. UTxOIndex u -> [(u, TokenBundle)]
UTxOIndex.toList UTxOIndex (UTxO ctx)
utxoSelected)
where
SelectionConstraints
{ TokenBundle -> TokenBundleSizeAssessment
assessTokenBundleSize :: TokenBundle -> TokenBundleSizeAssessment
$sel:assessTokenBundleSize:SelectionConstraints :: forall ctx.
SelectionConstraints ctx
-> TokenBundle -> TokenBundleSizeAssessment
assessTokenBundleSize
, Address ctx -> TokenMap -> Coin
computeMinimumAdaQuantity :: Address ctx -> TokenMap -> Coin
$sel:computeMinimumAdaQuantity:SelectionConstraints :: forall ctx.
SelectionConstraints ctx -> Address ctx -> TokenMap -> Coin
computeMinimumAdaQuantity
, SelectionSkeleton ctx -> Coin
computeMinimumCost :: SelectionSkeleton ctx -> Coin
$sel:computeMinimumCost:SelectionConstraints :: forall ctx.
SelectionConstraints ctx -> SelectionSkeleton ctx -> Coin
computeMinimumCost
, [(Address ctx, TokenBundle)] -> SelectionLimit
computeSelectionLimit :: [(Address ctx, TokenBundle)] -> SelectionLimit
$sel:computeSelectionLimit:SelectionConstraints :: forall ctx.
SelectionConstraints ctx
-> [(Address ctx, TokenBundle)] -> SelectionLimit
computeSelectionLimit
, Coin
maximumOutputAdaQuantity :: Coin
$sel:maximumOutputAdaQuantity:SelectionConstraints :: forall ctx. SelectionConstraints ctx -> Coin
maximumOutputAdaQuantity
, TokenQuantity
maximumOutputTokenQuantity :: TokenQuantity
$sel:maximumOutputTokenQuantity:SelectionConstraints :: forall ctx. SelectionConstraints ctx -> TokenQuantity
maximumOutputTokenQuantity
, Address ctx
maximumLengthChangeAddress :: Address ctx
$sel:maximumLengthChangeAddress:SelectionConstraints :: forall ctx. SelectionConstraints ctx -> Address ctx
maximumLengthChangeAddress
} = SelectionConstraints ctx
constraints
SelectionParams
{ NonEmpty (Address ctx, TokenBundle)
outputsToCover :: NonEmpty (Address ctx, TokenBundle)
$sel:outputsToCover:SelectionParams :: forall (f :: * -> *) ctx.
SelectionParamsOf f ctx -> f (Address ctx, TokenBundle)
outputsToCover
, UTxOSelection (UTxO ctx)
utxoAvailable :: UTxOSelection (UTxO ctx)
$sel:utxoAvailable:SelectionParams :: forall (f :: * -> *) ctx.
SelectionParamsOf f ctx -> UTxOSelection (UTxO ctx)
utxoAvailable
, Coin
extraCoinSource :: Coin
$sel:extraCoinSource:SelectionParams :: forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> Coin
extraCoinSource
, Coin
extraCoinSink :: Coin
$sel:extraCoinSink:SelectionParams :: forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> Coin
extraCoinSink
, TokenMap
assetsToMint :: TokenMap
$sel:assetsToMint:SelectionParams :: forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> TokenMap
assetsToMint
, TokenMap
assetsToBurn :: TokenMap
$sel:assetsToBurn:SelectionParams :: forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> TokenMap
assetsToBurn
, SelectionStrategy
selectionStrategy :: SelectionStrategy
$sel:selectionStrategy:SelectionParams :: forall (f :: * -> *) ctx.
SelectionParamsOf f ctx -> SelectionStrategy
selectionStrategy
} = SelectionParamsOf NonEmpty ctx
params
selectionLimitReachedError
:: [(UTxO ctx, TokenBundle)] -> m (Either (SelectionBalanceError ctx) a)
selectionLimitReachedError :: [(UTxO ctx, TokenBundle)]
-> m (Either (SelectionBalanceError ctx) a)
selectionLimitReachedError [(UTxO ctx, TokenBundle)]
inputsSelected =
Either (SelectionBalanceError ctx) a
-> m (Either (SelectionBalanceError ctx) a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either (SelectionBalanceError ctx) a
-> m (Either (SelectionBalanceError ctx) a))
-> Either (SelectionBalanceError ctx) a
-> m (Either (SelectionBalanceError ctx) a)
forall a b. (a -> b) -> a -> b
$ SelectionBalanceError ctx -> Either (SelectionBalanceError ctx) a
forall a b. a -> Either a b
Left (SelectionBalanceError ctx -> Either (SelectionBalanceError ctx) a)
-> SelectionBalanceError ctx
-> Either (SelectionBalanceError ctx) a
forall a b. (a -> b) -> a -> b
$ SelectionLimitReachedError ctx -> SelectionBalanceError ctx
forall ctx.
SelectionLimitReachedError ctx -> SelectionBalanceError ctx
SelectionLimitReached (SelectionLimitReachedError ctx -> SelectionBalanceError ctx)
-> SelectionLimitReachedError ctx -> SelectionBalanceError ctx
forall a b. (a -> b) -> a -> b
$ SelectionLimitReachedError :: forall ctx.
TokenBundle
-> [(UTxO ctx, TokenBundle)]
-> NonEmpty (Address ctx, TokenBundle)
-> SelectionLimitReachedError ctx
SelectionLimitReachedError
{ [(UTxO ctx, TokenBundle)]
inputsSelected :: [(UTxO ctx, TokenBundle)]
$sel:inputsSelected:SelectionLimitReachedError :: [(UTxO ctx, TokenBundle)]
inputsSelected
, TokenBundle
utxoBalanceRequired :: TokenBundle
$sel:utxoBalanceRequired:SelectionLimitReachedError :: TokenBundle
utxoBalanceRequired
, NonEmpty (Address ctx, TokenBundle)
outputsToCover :: NonEmpty (Address ctx, TokenBundle)
$sel:outputsToCover:SelectionLimitReachedError :: NonEmpty (Address ctx, TokenBundle)
outputsToCover
}
selectionLimit :: SelectionLimit
selectionLimit :: SelectionLimit
selectionLimit = [(Address ctx, TokenBundle)] -> SelectionLimit
computeSelectionLimit ([(Address ctx, TokenBundle)] -> SelectionLimit)
-> [(Address ctx, TokenBundle)] -> SelectionLimit
forall a b. (a -> b) -> a -> b
$ NonEmpty (Address ctx, TokenBundle) -> [(Address ctx, TokenBundle)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList NonEmpty (Address ctx, TokenBundle)
outputsToCover
utxoBalanceAvailable :: TokenBundle
utxoBalanceAvailable :: TokenBundle
utxoBalanceAvailable = SelectionParamsOf NonEmpty ctx -> TokenBundle
forall (f :: * -> *) ctx. SelectionParamsOf f ctx -> TokenBundle
computeUTxOBalanceAvailable SelectionParamsOf NonEmpty ctx
params
utxoBalanceRequired :: TokenBundle
utxoBalanceRequired :: TokenBundle
utxoBalanceRequired = SelectionParamsOf NonEmpty ctx -> TokenBundle
forall (f :: * -> *) ctx.
Foldable f =>
SelectionParamsOf f ctx -> TokenBundle
computeUTxOBalanceRequired SelectionParamsOf NonEmpty ctx
params
utxoBalanceSufficient :: Bool
utxoBalanceSufficient :: Bool
utxoBalanceSufficient = SelectionParamsOf NonEmpty ctx -> Bool
forall (f :: * -> *) ctx.
Foldable f =>
SelectionParamsOf f ctx -> Bool
isUTxOBalanceSufficient SelectionParamsOf NonEmpty ctx
params
predictChange :: UTxOSelectionNonEmpty (UTxO ctx) -> [Set AssetId]
predictChange :: UTxOSelectionNonEmpty (UTxO ctx) -> [Set AssetId]
predictChange UTxOSelectionNonEmpty (UTxO ctx)
s = (UnableToConstructChangeError -> [Set AssetId])
-> ([TokenBundle] -> [Set AssetId])
-> Either UnableToConstructChangeError [TokenBundle]
-> [Set AssetId]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
([Set AssetId] -> UnableToConstructChangeError -> [Set AssetId]
forall a b. a -> b -> a
const ([Set AssetId] -> UnableToConstructChangeError -> [Set AssetId])
-> [Set AssetId] -> UnableToConstructChangeError -> [Set AssetId]
forall a b. (a -> b) -> a -> b
$ UTxOIndex (UTxO ctx) -> [Set AssetId]
invariantResultWithNoCost (UTxOIndex (UTxO ctx) -> [Set AssetId])
-> UTxOIndex (UTxO ctx) -> [Set AssetId]
forall a b. (a -> b) -> a -> b
$ UTxOSelectionNonEmpty (UTxO ctx) -> UTxOIndex (UTxO ctx)
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> UTxOIndex u
UTxOSelection.selectedIndex UTxOSelectionNonEmpty (UTxO ctx)
s)
((TokenBundle -> Set AssetId) -> [TokenBundle] -> [Set AssetId]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TokenMap -> Set AssetId
TokenMap.getAssets (TokenMap -> Set AssetId)
-> (TokenBundle -> TokenMap) -> TokenBundle -> Set AssetId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle)
-> TokenBundle -> TokenMap
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"tokens"
((TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle)
(TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle
#tokens))
(MakeChangeCriteria (TokenMap -> Coin) TokenBundleSizeAssessor
-> Either UnableToConstructChangeError [TokenBundle]
makeChange MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
minCoinFor
-> bundleSizeAssessor
-> Coin
-> Coin
-> Coin
-> NonEmpty TokenBundle
-> NonEmpty TokenBundle
-> TokenMap
-> TokenMap
-> Coin
-> TokenQuantity
-> MakeChangeCriteria minCoinFor bundleSizeAssessor
MakeChangeCriteria
{ $sel:minCoinFor:MakeChangeCriteria :: TokenMap -> Coin
minCoinFor = TokenMap -> Coin
noMinimumCoin
, $sel:bundleSizeAssessor:MakeChangeCriteria :: TokenBundleSizeAssessor
bundleSizeAssessor = (TokenBundle -> TokenBundleSizeAssessment)
-> TokenBundleSizeAssessor
TokenBundleSizeAssessor TokenBundle -> TokenBundleSizeAssessment
assessTokenBundleSize
, $sel:requiredCost:MakeChangeCriteria :: Coin
requiredCost = Coin
noCost
, Coin
$sel:extraCoinSource:MakeChangeCriteria :: Coin
extraCoinSource :: Coin
extraCoinSource
, Coin
$sel:extraCoinSink:MakeChangeCriteria :: Coin
extraCoinSink :: Coin
extraCoinSink
, NonEmpty TokenBundle
$sel:inputBundles:MakeChangeCriteria :: NonEmpty TokenBundle
inputBundles :: NonEmpty TokenBundle
inputBundles
, NonEmpty TokenBundle
$sel:outputBundles:MakeChangeCriteria :: NonEmpty TokenBundle
outputBundles :: NonEmpty TokenBundle
outputBundles
, TokenMap
$sel:assetsToMint:MakeChangeCriteria :: TokenMap
assetsToMint :: TokenMap
assetsToMint
, TokenMap
$sel:assetsToBurn:MakeChangeCriteria :: TokenMap
assetsToBurn :: TokenMap
assetsToBurn
, Coin
$sel:maximumOutputAdaQuantity:MakeChangeCriteria :: Coin
maximumOutputAdaQuantity :: Coin
maximumOutputAdaQuantity
, TokenQuantity
$sel:maximumOutputTokenQuantity:MakeChangeCriteria :: TokenQuantity
maximumOutputTokenQuantity :: TokenQuantity
maximumOutputTokenQuantity
}
)
where
inputBundles :: NonEmpty TokenBundle
inputBundles = (UTxO ctx, TokenBundle) -> TokenBundle
forall a b. (a, b) -> b
snd ((UTxO ctx, TokenBundle) -> TokenBundle)
-> NonEmpty (UTxO ctx, TokenBundle) -> NonEmpty TokenBundle
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UTxOSelectionNonEmpty (UTxO ctx)
-> SelectedList UTxOSelectionNonEmpty (UTxO ctx)
forall (s :: * -> *) u.
IsUTxOSelection s u =>
s u -> SelectedList s u
UTxOSelection.selectedList UTxOSelectionNonEmpty (UTxO ctx)
s
outputBundles :: NonEmpty TokenBundle
outputBundles = (Address ctx, TokenBundle) -> TokenBundle
forall a b. (a, b) -> b
snd ((Address ctx, TokenBundle) -> TokenBundle)
-> NonEmpty (Address ctx, TokenBundle) -> NonEmpty TokenBundle
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (Address ctx, TokenBundle)
outputsToCover
noMinimumCoin :: TokenMap -> Coin
noMinimumCoin :: TokenMap -> Coin
noMinimumCoin = Coin -> TokenMap -> Coin
forall a b. a -> b -> a
const (Natural -> Coin
Coin Natural
0)
noCost :: Coin
noCost :: Coin
noCost = Natural -> Coin
Coin Natural
0
makeChangeRepeatedly
:: UTxOSelectionNonEmpty (UTxO ctx)
-> m (Either
(SelectionBalanceError ctx)
(SelectionResultOf NonEmpty ctx))
makeChangeRepeatedly :: UTxOSelectionNonEmpty (UTxO ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
makeChangeRepeatedly UTxOSelectionNonEmpty (UTxO ctx)
s = case Either UnableToConstructChangeError [TokenBundle]
mChangeGenerated of
Right [TokenBundle]
change | [TokenBundle] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TokenBundle]
change Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= NonEmpty (Address ctx, TokenBundle) -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length NonEmpty (Address ctx, TokenBundle)
outputsToCover ->
Either (SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)))
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall a b. (a -> b) -> a -> b
$ SelectionResultOf NonEmpty ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
forall a b. b -> Either a b
Right (SelectionResultOf NonEmpty ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
-> SelectionResultOf NonEmpty ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
forall a b. (a -> b) -> a -> b
$ [TokenBundle] -> SelectionResultOf NonEmpty ctx
mkSelectionResult [TokenBundle]
change
Right [TokenBundle]
change ->
UTxOSelectionNonEmpty (UTxO ctx)
-> m (Maybe (UTxOSelectionNonEmpty (UTxO ctx)))
selectOneEntry UTxOSelectionNonEmpty (UTxO ctx)
s m (Maybe (UTxOSelectionNonEmpty (UTxO ctx)))
-> (Maybe (UTxOSelectionNonEmpty (UTxO ctx))
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)))
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just UTxOSelectionNonEmpty (UTxO ctx)
s' ->
UTxOSelectionNonEmpty (UTxO ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
makeChangeRepeatedly UTxOSelectionNonEmpty (UTxO ctx)
s'
Maybe (UTxOSelectionNonEmpty (UTxO ctx))
Nothing ->
Either (SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)))
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall a b. (a -> b) -> a -> b
$ SelectionResultOf NonEmpty ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
forall a b. b -> Either a b
Right (SelectionResultOf NonEmpty ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
-> SelectionResultOf NonEmpty ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
forall a b. (a -> b) -> a -> b
$ [TokenBundle] -> SelectionResultOf NonEmpty ctx
mkSelectionResult [TokenBundle]
change
Left UnableToConstructChangeError
changeErr ->
UTxOSelectionNonEmpty (UTxO ctx)
-> m (Maybe (UTxOSelectionNonEmpty (UTxO ctx)))
selectOneEntry UTxOSelectionNonEmpty (UTxO ctx)
s m (Maybe (UTxOSelectionNonEmpty (UTxO ctx)))
-> (Maybe (UTxOSelectionNonEmpty (UTxO ctx))
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)))
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just UTxOSelectionNonEmpty (UTxO ctx)
s' ->
UTxOSelectionNonEmpty (UTxO ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
makeChangeRepeatedly UTxOSelectionNonEmpty (UTxO ctx)
s'
Maybe (UTxOSelectionNonEmpty (UTxO ctx))
Nothing ->
Either (SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)))
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
-> m (Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
forall a b. (a -> b) -> a -> b
$ SelectionBalanceError ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
forall a b. a -> Either a b
Left (SelectionBalanceError ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx))
-> SelectionBalanceError ctx
-> Either
(SelectionBalanceError ctx) (SelectionResultOf NonEmpty ctx)
forall a b. (a -> b) -> a -> b
$ UnableToConstructChangeError -> SelectionBalanceError ctx
forall ctx.
UnableToConstructChangeError -> SelectionBalanceError ctx
UnableToConstructChange UnableToConstructChangeError
changeErr
where
mChangeGenerated :: Either UnableToConstructChangeError [TokenBundle]
mChangeGenerated :: Either UnableToConstructChangeError [TokenBundle]
mChangeGenerated = MakeChangeCriteria (TokenMap -> Coin) TokenBundleSizeAssessor
-> Either UnableToConstructChangeError [TokenBundle]
makeChange MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
minCoinFor
-> bundleSizeAssessor
-> Coin
-> Coin
-> Coin
-> NonEmpty TokenBundle
-> NonEmpty TokenBundle
-> TokenMap
-> TokenMap
-> Coin
-> TokenQuantity
-> MakeChangeCriteria minCoinFor bundleSizeAssessor
MakeChangeCriteria
{ $sel:minCoinFor:MakeChangeCriteria :: TokenMap -> Coin
minCoinFor = Address ctx -> TokenMap -> Coin
computeMinimumAdaQuantity Address ctx
maximumLengthChangeAddress
, $sel:bundleSizeAssessor:MakeChangeCriteria :: TokenBundleSizeAssessor
bundleSizeAssessor = (TokenBundle -> TokenBundleSizeAssessment)
-> TokenBundleSizeAssessor
TokenBundleSizeAssessor TokenBundle -> TokenBundleSizeAssessment
assessTokenBundleSize
, Coin
requiredCost :: Coin
$sel:requiredCost:MakeChangeCriteria :: Coin
requiredCost
, Coin
$sel:extraCoinSource:MakeChangeCriteria :: Coin
extraCoinSource :: Coin
extraCoinSource
, Coin
$sel:extraCoinSink:MakeChangeCriteria :: Coin
extraCoinSink :: Coin
extraCoinSink
, $sel:inputBundles:MakeChangeCriteria :: NonEmpty TokenBundle
inputBundles = (UTxO ctx, TokenBundle) -> TokenBundle
forall a b. (a, b) -> b
snd ((UTxO ctx, TokenBundle) -> TokenBundle)
-> NonEmpty (UTxO ctx, TokenBundle) -> NonEmpty TokenBundle
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (UTxO ctx, TokenBundle)
SelectedList UTxOSelectionNonEmpty (UTxO ctx)
inputsSelected
, $sel:outputBundles:MakeChangeCriteria :: NonEmpty TokenBundle
outputBundles = (Address ctx, TokenBundle) -> TokenBundle
forall a b. (a, b) -> b
snd ((Address ctx, TokenBundle) -> TokenBundle)
-> NonEmpty (Address ctx, TokenBundle) -> NonEmpty TokenBundle
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (Address ctx, TokenBundle)
outputsToCover
, TokenMap
$sel:assetsToMint:MakeChangeCriteria :: TokenMap
assetsToMint :: TokenMap
assetsToMint
, TokenMap
$sel:assetsToBurn:MakeChangeCriteria :: TokenMap
assetsToBurn :: TokenMap
assetsToBurn
, Coin
$sel:maximumOutputAdaQuantity:MakeChangeCriteria :: Coin
maximumOutputAdaQuantity :: Coin
maximumOutputAdaQuantity
, TokenQuantity
$sel:maximumOutputTokenQuantity:MakeChangeCriteria :: TokenQuantity
maximumOutputTokenQuantity :: TokenQuantity
maximumOutputTokenQuantity
}
mkSelectionResult :: [TokenBundle] -> SelectionResultOf NonEmpty ctx
mkSelectionResult :: [TokenBundle] -> SelectionResultOf NonEmpty ctx
mkSelectionResult [TokenBundle]
changeGenerated = SelectionResult :: forall (f :: * -> *) ctx.
NonEmpty (UTxO ctx, TokenBundle)
-> Coin
-> Coin
-> f (Address ctx, TokenBundle)
-> [TokenBundle]
-> TokenMap
-> TokenMap
-> SelectionResultOf f ctx
SelectionResult
{ NonEmpty (UTxO ctx, TokenBundle)
SelectedList UTxOSelectionNonEmpty (UTxO ctx)
inputsSelected :: SelectedList UTxOSelectionNonEmpty (UTxO ctx)
$sel:inputsSelected:SelectionResult :: NonEmpty (UTxO ctx, TokenBundle)
inputsSelected
, Coin
extraCoinSource :: Coin
$sel:extraCoinSource:SelectionResult :: Coin
extraCoinSource
, Coin
extraCoinSink :: Coin
$sel:extraCoinSink:SelectionResult :: Coin
extraCoinSink
, $sel:changeGenerated:SelectionResult :: [TokenBundle]
changeGenerated = [TokenBundle]
changeGenerated
, $sel:outputsCovered:SelectionResult :: NonEmpty (Address ctx, TokenBundle)
outputsCovered = NonEmpty (Address ctx, TokenBundle)
outputsToCover
, TokenMap
assetsToMint :: TokenMap
$sel:assetsToMint:SelectionResult :: TokenMap
assetsToMint
, TokenMap
assetsToBurn :: TokenMap
$sel:assetsToBurn:SelectionResult :: TokenMap
assetsToBurn
}
selectOneEntry :: UTxOSelectionNonEmpty (UTxO ctx)
-> m (Maybe (UTxOSelectionNonEmpty (UTxO ctx)))
selectOneEntry = Asset
-> SelectionLimit
-> UTxOSelectionNonEmpty (UTxO ctx)
-> m (Maybe (UTxOSelectionNonEmpty (UTxO ctx)))
forall (m :: * -> *) u (utxoSelection :: * -> *).
(MonadRandom m, Ord u, IsUTxOSelection utxoSelection u) =>
Asset
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
selectQuantityOf Asset
AssetLovelace SelectionLimit
selectionLimit
requiredCost :: Coin
requiredCost = SelectionSkeleton ctx -> Coin
computeMinimumCost SelectionSkeleton :: forall ctx.
Int
-> [(Address ctx, TokenBundle)]
-> [Set AssetId]
-> SelectionSkeleton ctx
SelectionSkeleton
{ $sel:skeletonInputCount:SelectionSkeleton :: Int
skeletonInputCount = UTxOSelectionNonEmpty (UTxO ctx) -> Int
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> Int
UTxOSelection.selectedSize UTxOSelectionNonEmpty (UTxO ctx)
s
, $sel:skeletonOutputs:SelectionSkeleton :: [(Address ctx, TokenBundle)]
skeletonOutputs = NonEmpty (Address ctx, TokenBundle) -> [(Address ctx, TokenBundle)]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty (Address ctx, TokenBundle)
outputsToCover
, [Set AssetId]
skeletonChange :: [Set AssetId]
$sel:skeletonChange:SelectionSkeleton :: [Set AssetId]
skeletonChange
}
skeletonChange :: [Set AssetId]
skeletonChange = UTxOSelectionNonEmpty (UTxO ctx) -> [Set AssetId]
predictChange UTxOSelectionNonEmpty (UTxO ctx)
s
inputsSelected :: SelectedList UTxOSelectionNonEmpty (UTxO ctx)
inputsSelected = UTxOSelectionNonEmpty (UTxO ctx)
-> SelectedList UTxOSelectionNonEmpty (UTxO ctx)
forall (s :: * -> *) u.
IsUTxOSelection s u =>
s u -> SelectedList s u
UTxOSelection.selectedList UTxOSelectionNonEmpty (UTxO ctx)
s
invariantResultWithNoCost :: UTxOIndex (UTxO ctx) -> [Set AssetId]
invariantResultWithNoCost UTxOIndex (UTxO ctx)
inputs_ = String -> [Set AssetId]
forall a. HasCallStack => String -> a
error (String -> [Set AssetId]) -> String -> [Set AssetId]
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
[ Item [String]
"performSelection: couldn't construct change for a selection with no "
, Item [String]
"minimum coin value and no cost!"
, String
"inputs: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> UTxOIndex (UTxO ctx) -> String
forall a. Show a => a -> String
show UTxOIndex (UTxO ctx)
inputs_
, String
"extra coin source: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Coin -> String
forall a. Show a => a -> String
show Coin
extraCoinSource
, String
"extra coin sink: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Coin -> String
forall a. Show a => a -> String
show Coin
extraCoinSink
, String
"outputs: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> NonEmpty (Address ctx, TokenBundle) -> String
forall a. Show a => a -> String
show NonEmpty (Address ctx, TokenBundle)
outputsToCover
]
data RunSelectionParams u = RunSelectionParams
{ RunSelectionParams u -> SelectionLimit
selectionLimit :: SelectionLimit
, RunSelectionParams u -> UTxOSelection u
utxoAvailable :: (UTxOSelection u)
, RunSelectionParams u -> TokenBundle
minimumBalance :: TokenBundle
, RunSelectionParams u -> SelectionStrategy
selectionStrategy :: SelectionStrategy
}
deriving (RunSelectionParams u -> RunSelectionParams u -> Bool
(RunSelectionParams u -> RunSelectionParams u -> Bool)
-> (RunSelectionParams u -> RunSelectionParams u -> Bool)
-> Eq (RunSelectionParams u)
forall u.
Eq u =>
RunSelectionParams u -> RunSelectionParams u -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RunSelectionParams u -> RunSelectionParams u -> Bool
$c/= :: forall u.
Eq u =>
RunSelectionParams u -> RunSelectionParams u -> Bool
== :: RunSelectionParams u -> RunSelectionParams u -> Bool
$c== :: forall u.
Eq u =>
RunSelectionParams u -> RunSelectionParams u -> Bool
Eq, (forall x. RunSelectionParams u -> Rep (RunSelectionParams u) x)
-> (forall x. Rep (RunSelectionParams u) x -> RunSelectionParams u)
-> Generic (RunSelectionParams u)
forall x. Rep (RunSelectionParams u) x -> RunSelectionParams u
forall x. RunSelectionParams u -> Rep (RunSelectionParams u) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall u x. Rep (RunSelectionParams u) x -> RunSelectionParams u
forall u x. RunSelectionParams u -> Rep (RunSelectionParams u) x
$cto :: forall u x. Rep (RunSelectionParams u) x -> RunSelectionParams u
$cfrom :: forall u x. RunSelectionParams u -> Rep (RunSelectionParams u) x
Generic, Int -> RunSelectionParams u -> ShowS
[RunSelectionParams u] -> ShowS
RunSelectionParams u -> String
(Int -> RunSelectionParams u -> ShowS)
-> (RunSelectionParams u -> String)
-> ([RunSelectionParams u] -> ShowS)
-> Show (RunSelectionParams u)
forall u. Show u => Int -> RunSelectionParams u -> ShowS
forall u. Show u => [RunSelectionParams u] -> ShowS
forall u. Show u => RunSelectionParams u -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RunSelectionParams u] -> ShowS
$cshowList :: forall u. Show u => [RunSelectionParams u] -> ShowS
show :: RunSelectionParams u -> String
$cshow :: forall u. Show u => RunSelectionParams u -> String
showsPrec :: Int -> RunSelectionParams u -> ShowS
$cshowsPrec :: forall u. Show u => Int -> RunSelectionParams u -> ShowS
Show)
runSelectionNonEmpty
:: (MonadRandom m, Ord u)
=> RunSelectionParams u
-> m (Maybe (UTxOSelectionNonEmpty u))
runSelectionNonEmpty :: RunSelectionParams u -> m (Maybe (UTxOSelectionNonEmpty u))
runSelectionNonEmpty = (UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> m (UTxOSelection u) -> m (Maybe (UTxOSelectionNonEmpty u))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
(=<<)
((UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> m (UTxOSelection u) -> m (Maybe (UTxOSelectionNonEmpty u)))
-> (RunSelectionParams u
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> RunSelectionParams u
-> m (UTxOSelection u)
-> m (Maybe (UTxOSelectionNonEmpty u))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
forall (m :: * -> *) u.
Monad m =>
(UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
runSelectionNonEmptyWith
((UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> (RunSelectionParams u
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> RunSelectionParams u
-> UTxOSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Asset
-> SelectionLimit
-> UTxOSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall (m :: * -> *) u (utxoSelection :: * -> *).
(MonadRandom m, Ord u, IsUTxOSelection utxoSelection u) =>
Asset
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
selectQuantityOf Asset
AssetLovelace
(SelectionLimit
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> (RunSelectionParams u -> SelectionLimit)
-> RunSelectionParams u
-> UTxOSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((SelectionLimit -> Const SelectionLimit SelectionLimit)
-> RunSelectionParams u
-> Const SelectionLimit (RunSelectionParams u))
-> RunSelectionParams u -> SelectionLimit
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"selectionLimit"
((SelectionLimit -> Const SelectionLimit SelectionLimit)
-> RunSelectionParams u
-> Const SelectionLimit (RunSelectionParams u))
(SelectionLimit -> Const SelectionLimit SelectionLimit)
-> RunSelectionParams u
-> Const SelectionLimit (RunSelectionParams u)
#selectionLimit
(RunSelectionParams u
-> m (UTxOSelection u) -> m (Maybe (UTxOSelectionNonEmpty u)))
-> (RunSelectionParams u -> m (UTxOSelection u))
-> RunSelectionParams u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RunSelectionParams u -> m (UTxOSelection u)
forall (m :: * -> *) u.
(MonadRandom m, Ord u) =>
RunSelectionParams u -> m (UTxOSelection u)
runSelection
runSelectionNonEmptyWith
:: Monad m
=> (UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> UTxOSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
runSelectionNonEmptyWith :: (UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
runSelectionNonEmptyWith UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
selectSingleEntry UTxOSelection u
result =
UTxOSelection u -> Maybe (UTxOSelectionNonEmpty u)
forall (s :: * -> *) u.
IsUTxOSelection s u =>
s u -> Maybe (UTxOSelectionNonEmpty u)
UTxOSelection.toNonEmpty UTxOSelection u
result Maybe (UTxOSelectionNonEmpty u)
-> (Maybe (UTxOSelectionNonEmpty u)
-> m (Maybe (UTxOSelectionNonEmpty u)))
-> m (Maybe (UTxOSelectionNonEmpty u))
forall a b. a -> (a -> b) -> b
& m (Maybe (UTxOSelectionNonEmpty u))
-> (UTxOSelectionNonEmpty u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> Maybe (UTxOSelectionNonEmpty u)
-> m (Maybe (UTxOSelectionNonEmpty u))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(UTxOSelection u
result UTxOSelection u
-> (UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> m (Maybe (UTxOSelectionNonEmpty u))
forall a b. a -> (a -> b) -> b
& UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
selectSingleEntry)
(Maybe (UTxOSelectionNonEmpty u)
-> m (Maybe (UTxOSelectionNonEmpty u))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (UTxOSelectionNonEmpty u)
-> m (Maybe (UTxOSelectionNonEmpty u)))
-> (UTxOSelectionNonEmpty u -> Maybe (UTxOSelectionNonEmpty u))
-> UTxOSelectionNonEmpty u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTxOSelectionNonEmpty u -> Maybe (UTxOSelectionNonEmpty u)
forall a. a -> Maybe a
Just)
runSelection
:: forall m u. (MonadRandom m, Ord u)
=> RunSelectionParams u
-> m (UTxOSelection u)
runSelection :: RunSelectionParams u -> m (UTxOSelection u)
runSelection RunSelectionParams u
params =
UTxOSelection u
-> (UTxOSelectionNonEmpty u -> UTxOSelection u)
-> [UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))]
-> m (UTxOSelection u)
forall (m :: * -> *) s s'.
Monad m =>
s -> (s' -> s) -> [s -> m (Maybe s')] -> m s
runRoundRobinM UTxOSelection u
utxoAvailable UTxOSelectionNonEmpty u -> UTxOSelection u
forall u. UTxOSelectionNonEmpty u -> UTxOSelection u
UTxOSelection.fromNonEmpty [UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))]
selectors
where
RunSelectionParams
{ SelectionLimit
selectionLimit :: SelectionLimit
$sel:selectionLimit:RunSelectionParams :: forall u. RunSelectionParams u -> SelectionLimit
selectionLimit
, UTxOSelection u
utxoAvailable :: UTxOSelection u
$sel:utxoAvailable:RunSelectionParams :: forall u. RunSelectionParams u -> UTxOSelection u
utxoAvailable
, TokenBundle
minimumBalance :: TokenBundle
$sel:minimumBalance:RunSelectionParams :: forall u. RunSelectionParams u -> TokenBundle
minimumBalance
, SelectionStrategy
selectionStrategy :: SelectionStrategy
$sel:selectionStrategy:RunSelectionParams :: forall u. RunSelectionParams u -> SelectionStrategy
selectionStrategy
} = RunSelectionParams u
params
selectors :: [UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))]
selectors :: [UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))]
selectors =
[UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))]
-> [UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))]
forall a. [a] -> [a]
reverse (UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
coinSelector (UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> [UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))]
-> [UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))]
forall a. a -> [a] -> [a]
: ((AssetId, TokenQuantity)
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> [(AssetId, TokenQuantity)]
-> [UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (AssetId, TokenQuantity)
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
assetSelector [(AssetId, TokenQuantity)]
minimumAssetQuantities)
where
assetSelector :: (AssetId, TokenQuantity)
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
assetSelector = SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
forall (m :: * -> *) state state'.
Monad m =>
SelectionLens m state state' -> state -> m (Maybe state')
runSelectionStep (SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> ((AssetId, TokenQuantity)
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u))
-> (AssetId, TokenQuantity)
-> UTxOSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
SelectionLimit
-> SelectionStrategy
-> (AssetId, TokenQuantity)
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
forall (m :: * -> *) u.
(MonadRandom m, Ord u) =>
SelectionLimit
-> SelectionStrategy
-> (AssetId, TokenQuantity)
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
assetSelectionLens SelectionLimit
selectionLimit SelectionStrategy
selectionStrategy
coinSelector :: UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
coinSelector = SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
forall (m :: * -> *) state state'.
Monad m =>
SelectionLens m state state' -> state -> m (Maybe state')
runSelectionStep (SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
-> UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u)))
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
-> UTxOSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall a b. (a -> b) -> a -> b
$
SelectionLimit
-> SelectionStrategy
-> Coin
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
forall (m :: * -> *) u.
(MonadRandom m, Ord u) =>
SelectionLimit
-> SelectionStrategy
-> Coin
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
coinSelectionLens SelectionLimit
selectionLimit SelectionStrategy
selectionStrategy
Coin
minimumCoinQuantity
(Coin
minimumCoinQuantity, [(AssetId, TokenQuantity)]
minimumAssetQuantities) =
TokenBundle -> (Coin, [(AssetId, TokenQuantity)])
TokenBundle.toFlatList TokenBundle
minimumBalance
assetSelectionLens
:: (MonadRandom m, Ord u)
=> SelectionLimit
-> SelectionStrategy
-> (AssetId, TokenQuantity)
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
assetSelectionLens :: SelectionLimit
-> SelectionStrategy
-> (AssetId, TokenQuantity)
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
assetSelectionLens SelectionLimit
limit SelectionStrategy
strategy (AssetId
asset, TokenQuantity
minimumAssetQuantity) = SelectionLens :: forall (m :: * -> *) state state'.
(state -> Natural)
-> (state' -> Natural)
-> (state -> m (Maybe state'))
-> Natural
-> SelectionStrategy
-> SelectionLens m state state'
SelectionLens
{ $sel:currentQuantity:SelectionLens :: UTxOSelection u -> Natural
currentQuantity = AssetId -> UTxOSelection u -> Natural
forall (s :: * -> *) u.
IsUTxOSelection s u =>
AssetId -> s u -> Natural
selectedAssetQuantity AssetId
asset
, $sel:updatedQuantity:SelectionLens :: UTxOSelectionNonEmpty u -> Natural
updatedQuantity = AssetId -> UTxOSelectionNonEmpty u -> Natural
forall (s :: * -> *) u.
IsUTxOSelection s u =>
AssetId -> s u -> Natural
selectedAssetQuantity AssetId
asset
, $sel:minimumQuantity:SelectionLens :: Natural
minimumQuantity = TokenQuantity -> Natural
unTokenQuantity TokenQuantity
minimumAssetQuantity
, $sel:selectQuantity:SelectionLens :: UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
selectQuantity = Asset
-> SelectionLimit
-> UTxOSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall (m :: * -> *) u (utxoSelection :: * -> *).
(MonadRandom m, Ord u, IsUTxOSelection utxoSelection u) =>
Asset
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
selectQuantityOf (AssetId -> Asset
Asset AssetId
asset) SelectionLimit
limit
, $sel:selectionStrategy:SelectionLens :: SelectionStrategy
selectionStrategy = SelectionStrategy
strategy
}
coinSelectionLens
:: (MonadRandom m, Ord u)
=> SelectionLimit
-> SelectionStrategy
-> Coin
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
coinSelectionLens :: SelectionLimit
-> SelectionStrategy
-> Coin
-> SelectionLens m (UTxOSelection u) (UTxOSelectionNonEmpty u)
coinSelectionLens SelectionLimit
limit SelectionStrategy
strategy Coin
minimumCoinQuantity = SelectionLens :: forall (m :: * -> *) state state'.
(state -> Natural)
-> (state' -> Natural)
-> (state -> m (Maybe state'))
-> Natural
-> SelectionStrategy
-> SelectionLens m state state'
SelectionLens
{ $sel:currentQuantity:SelectionLens :: UTxOSelection u -> Natural
currentQuantity = UTxOSelection u -> Natural
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> Natural
selectedCoinQuantity
, $sel:updatedQuantity:SelectionLens :: UTxOSelectionNonEmpty u -> Natural
updatedQuantity = UTxOSelectionNonEmpty u -> Natural
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> Natural
selectedCoinQuantity
, $sel:minimumQuantity:SelectionLens :: Natural
minimumQuantity = Natural -> Natural
forall a b.
(Integral a, Integral b, IsIntSubType a b ~ 'True) =>
a -> b
intCast (Natural -> Natural) -> Natural -> Natural
forall a b. (a -> b) -> a -> b
$ Coin -> Natural
unCoin Coin
minimumCoinQuantity
, $sel:selectQuantity:SelectionLens :: UTxOSelection u -> m (Maybe (UTxOSelectionNonEmpty u))
selectQuantity = Asset
-> SelectionLimit
-> UTxOSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall (m :: * -> *) u (utxoSelection :: * -> *).
(MonadRandom m, Ord u, IsUTxOSelection utxoSelection u) =>
Asset
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
selectQuantityOf Asset
AssetLovelace SelectionLimit
limit
, $sel:selectionStrategy:SelectionLens :: SelectionStrategy
selectionStrategy = SelectionStrategy
strategy
}
selectQuantityOf
:: (MonadRandom m, Ord u)
=> IsUTxOSelection utxoSelection u
=> Asset
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
selectQuantityOf :: Asset
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
selectQuantityOf Asset
a = NonEmpty (SelectionFilter Asset)
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
forall (m :: * -> *) (utxoSelection :: * -> *) u.
(MonadRandom m, Ord u, IsUTxOSelection utxoSelection u) =>
NonEmpty (SelectionFilter Asset)
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
selectMatchingQuantity
[ Asset -> SelectionFilter Asset
forall asset. asset -> SelectionFilter asset
SelectSingleton Asset
a
, Asset -> SelectionFilter Asset
forall asset. asset -> SelectionFilter asset
SelectPairWith Asset
a
, Asset -> SelectionFilter Asset
forall asset. asset -> SelectionFilter asset
SelectAnyWith Asset
a
]
selectMatchingQuantity
:: forall m utxoSelection u. (MonadRandom m, Ord u)
=> IsUTxOSelection utxoSelection u
=> NonEmpty (SelectionFilter Asset)
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
selectMatchingQuantity :: NonEmpty (SelectionFilter Asset)
-> SelectionLimit
-> utxoSelection u
-> m (Maybe (UTxOSelectionNonEmpty u))
selectMatchingQuantity NonEmpty (SelectionFilter Asset)
filters SelectionLimit
limit utxoSelection u
s
| Bool
limitReached =
Maybe (UTxOSelectionNonEmpty u)
-> m (Maybe (UTxOSelectionNonEmpty u))
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (UTxOSelectionNonEmpty u)
forall a. Maybe a
Nothing
| Bool
otherwise =
(((u, TokenBundle), UTxOIndex u) -> Maybe (UTxOSelectionNonEmpty u)
updateState (((u, TokenBundle), UTxOIndex u)
-> Maybe (UTxOSelectionNonEmpty u))
-> Maybe ((u, TokenBundle), UTxOIndex u)
-> Maybe (UTxOSelectionNonEmpty u)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) (Maybe ((u, TokenBundle), UTxOIndex u)
-> Maybe (UTxOSelectionNonEmpty u))
-> m (Maybe ((u, TokenBundle), UTxOIndex u))
-> m (Maybe (UTxOSelectionNonEmpty u))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UTxOIndex u
-> NonEmpty (SelectionFilter Asset)
-> m (Maybe ((u, TokenBundle), UTxOIndex u))
forall (m :: * -> *) u.
(MonadRandom m, Ord u) =>
UTxOIndex u
-> NonEmpty (SelectionFilter Asset)
-> m (Maybe ((u, TokenBundle), UTxOIndex u))
UTxOIndex.selectRandomWithPriority
(utxoSelection u -> UTxOIndex u
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> UTxOIndex u
UTxOSelection.leftoverIndex utxoSelection u
s) NonEmpty (SelectionFilter Asset)
filters
where
limitReached :: Bool
limitReached = case SelectionLimit
limit of
MaximumInputLimit Int
m -> utxoSelection u -> Int
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> Int
UTxOSelection.selectedSize utxoSelection u
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
m
SelectionLimit
NoLimit -> Bool
False
updateState
:: ((u, TokenBundle), UTxOIndex u) -> Maybe (UTxOSelectionNonEmpty u)
updateState :: ((u, TokenBundle), UTxOIndex u) -> Maybe (UTxOSelectionNonEmpty u)
updateState ((u
i, TokenBundle
_b), UTxOIndex u
_remaining) = u -> utxoSelection u -> Maybe (UTxOSelectionNonEmpty u)
forall (s :: * -> *) u.
(IsUTxOSelection s u, Ord u) =>
u -> s u -> Maybe (UTxOSelectionNonEmpty u)
UTxOSelection.select u
i utxoSelection u
s
data SelectionLens m state state' = SelectionLens
{ SelectionLens m state state' -> state -> Natural
currentQuantity
:: state -> Natural
, SelectionLens m state state' -> state' -> Natural
updatedQuantity
:: state' -> Natural
, SelectionLens m state state' -> state -> m (Maybe state')
selectQuantity
:: state -> m (Maybe state')
, SelectionLens m state state' -> Natural
minimumQuantity
:: Natural
, SelectionLens m state state' -> SelectionStrategy
selectionStrategy
:: SelectionStrategy
}
runSelectionStep
:: forall m state state'. Monad m
=> SelectionLens m state state'
-> state
-> m (Maybe state')
runSelectionStep :: SelectionLens m state state' -> state -> m (Maybe state')
runSelectionStep SelectionLens m state state'
lens state
s
| state -> Natural
currentQuantity state
s Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
< Natural
minimumQuantity =
state -> m (Maybe state')
selectQuantity state
s
| Bool
otherwise =
(state' -> Maybe state'
requireImprovement (state' -> Maybe state') -> Maybe state' -> Maybe state'
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) (Maybe state' -> Maybe state')
-> m (Maybe state') -> m (Maybe state')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> state -> m (Maybe state')
selectQuantity state
s
where
SelectionLens
{ state -> Natural
currentQuantity :: state -> Natural
$sel:currentQuantity:SelectionLens :: forall (m :: * -> *) state state'.
SelectionLens m state state' -> state -> Natural
currentQuantity
, state' -> Natural
updatedQuantity :: state' -> Natural
$sel:updatedQuantity:SelectionLens :: forall (m :: * -> *) state state'.
SelectionLens m state state' -> state' -> Natural
updatedQuantity
, Natural
minimumQuantity :: Natural
$sel:minimumQuantity:SelectionLens :: forall (m :: * -> *) state state'.
SelectionLens m state state' -> Natural
minimumQuantity
, state -> m (Maybe state')
selectQuantity :: state -> m (Maybe state')
$sel:selectQuantity:SelectionLens :: forall (m :: * -> *) state state'.
SelectionLens m state state' -> state -> m (Maybe state')
selectQuantity
, SelectionStrategy
selectionStrategy :: SelectionStrategy
$sel:selectionStrategy:SelectionLens :: forall (m :: * -> *) state state'.
SelectionLens m state state' -> SelectionStrategy
selectionStrategy
} = SelectionLens m state state'
lens
requireImprovement :: state' -> Maybe state'
requireImprovement :: state' -> Maybe state'
requireImprovement state'
s'
| state' -> Natural
updatedDistanceFromTarget state'
s' Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
< state -> Natural
currentDistanceFromTarget state
s = state' -> Maybe state'
forall a. a -> Maybe a
Just state'
s'
| Bool
otherwise = Maybe state'
forall a. Maybe a
Nothing
currentDistanceFromTarget :: state -> Natural
currentDistanceFromTarget :: state -> Natural
currentDistanceFromTarget = Natural -> Natural -> Natural
distance Natural
targetQuantity (Natural -> Natural) -> (state -> Natural) -> state -> Natural
forall b c a. (b -> c) -> (a -> b) -> a -> c
. state -> Natural
currentQuantity
updatedDistanceFromTarget :: state' -> Natural
updatedDistanceFromTarget :: state' -> Natural
updatedDistanceFromTarget = Natural -> Natural -> Natural
distance Natural
targetQuantity (Natural -> Natural) -> (state' -> Natural) -> state' -> Natural
forall b c a. (b -> c) -> (a -> b) -> a -> c
. state' -> Natural
updatedQuantity
targetMultiplier :: Natural
targetMultiplier :: Natural
targetMultiplier = case SelectionStrategy
selectionStrategy of
SelectionStrategy
SelectionStrategyMinimal -> Natural
1
SelectionStrategy
SelectionStrategyOptimal -> Natural
2
targetQuantity :: Natural
targetQuantity :: Natural
targetQuantity = Natural
minimumQuantity Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
* Natural
targetMultiplier
data MakeChangeCriteria minCoinFor bundleSizeAssessor = MakeChangeCriteria
{ MakeChangeCriteria minCoinFor bundleSizeAssessor -> minCoinFor
minCoinFor :: minCoinFor
, MakeChangeCriteria minCoinFor bundleSizeAssessor
-> bundleSizeAssessor
bundleSizeAssessor :: bundleSizeAssessor
, MakeChangeCriteria minCoinFor bundleSizeAssessor -> Coin
requiredCost :: Coin
, :: Coin
, :: Coin
, MakeChangeCriteria minCoinFor bundleSizeAssessor
-> NonEmpty TokenBundle
inputBundles :: NonEmpty TokenBundle
, MakeChangeCriteria minCoinFor bundleSizeAssessor
-> NonEmpty TokenBundle
outputBundles :: NonEmpty TokenBundle
, MakeChangeCriteria minCoinFor bundleSizeAssessor -> TokenMap
assetsToMint :: TokenMap
, MakeChangeCriteria minCoinFor bundleSizeAssessor -> TokenMap
assetsToBurn :: TokenMap
, MakeChangeCriteria minCoinFor bundleSizeAssessor -> Coin
maximumOutputAdaQuantity
:: Coin
, MakeChangeCriteria minCoinFor bundleSizeAssessor -> TokenQuantity
maximumOutputTokenQuantity
:: TokenQuantity
} deriving (MakeChangeCriteria minCoinFor bundleSizeAssessor
-> MakeChangeCriteria minCoinFor bundleSizeAssessor -> Bool
(MakeChangeCriteria minCoinFor bundleSizeAssessor
-> MakeChangeCriteria minCoinFor bundleSizeAssessor -> Bool)
-> (MakeChangeCriteria minCoinFor bundleSizeAssessor
-> MakeChangeCriteria minCoinFor bundleSizeAssessor -> Bool)
-> Eq (MakeChangeCriteria minCoinFor bundleSizeAssessor)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall minCoinFor bundleSizeAssessor.
(Eq minCoinFor, Eq bundleSizeAssessor) =>
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> MakeChangeCriteria minCoinFor bundleSizeAssessor -> Bool
/= :: MakeChangeCriteria minCoinFor bundleSizeAssessor
-> MakeChangeCriteria minCoinFor bundleSizeAssessor -> Bool
$c/= :: forall minCoinFor bundleSizeAssessor.
(Eq minCoinFor, Eq bundleSizeAssessor) =>
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> MakeChangeCriteria minCoinFor bundleSizeAssessor -> Bool
== :: MakeChangeCriteria minCoinFor bundleSizeAssessor
-> MakeChangeCriteria minCoinFor bundleSizeAssessor -> Bool
$c== :: forall minCoinFor bundleSizeAssessor.
(Eq minCoinFor, Eq bundleSizeAssessor) =>
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> MakeChangeCriteria minCoinFor bundleSizeAssessor -> Bool
Eq, (forall x.
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> Rep (MakeChangeCriteria minCoinFor bundleSizeAssessor) x)
-> (forall x.
Rep (MakeChangeCriteria minCoinFor bundleSizeAssessor) x
-> MakeChangeCriteria minCoinFor bundleSizeAssessor)
-> Generic (MakeChangeCriteria minCoinFor bundleSizeAssessor)
forall x.
Rep (MakeChangeCriteria minCoinFor bundleSizeAssessor) x
-> MakeChangeCriteria minCoinFor bundleSizeAssessor
forall x.
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> Rep (MakeChangeCriteria minCoinFor bundleSizeAssessor) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall minCoinFor bundleSizeAssessor x.
Rep (MakeChangeCriteria minCoinFor bundleSizeAssessor) x
-> MakeChangeCriteria minCoinFor bundleSizeAssessor
forall minCoinFor bundleSizeAssessor x.
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> Rep (MakeChangeCriteria minCoinFor bundleSizeAssessor) x
$cto :: forall minCoinFor bundleSizeAssessor x.
Rep (MakeChangeCriteria minCoinFor bundleSizeAssessor) x
-> MakeChangeCriteria minCoinFor bundleSizeAssessor
$cfrom :: forall minCoinFor bundleSizeAssessor x.
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> Rep (MakeChangeCriteria minCoinFor bundleSizeAssessor) x
Generic, Int -> MakeChangeCriteria minCoinFor bundleSizeAssessor -> ShowS
[MakeChangeCriteria minCoinFor bundleSizeAssessor] -> ShowS
MakeChangeCriteria minCoinFor bundleSizeAssessor -> String
(Int -> MakeChangeCriteria minCoinFor bundleSizeAssessor -> ShowS)
-> (MakeChangeCriteria minCoinFor bundleSizeAssessor -> String)
-> ([MakeChangeCriteria minCoinFor bundleSizeAssessor] -> ShowS)
-> Show (MakeChangeCriteria minCoinFor bundleSizeAssessor)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall minCoinFor bundleSizeAssessor.
(Show minCoinFor, Show bundleSizeAssessor) =>
Int -> MakeChangeCriteria minCoinFor bundleSizeAssessor -> ShowS
forall minCoinFor bundleSizeAssessor.
(Show minCoinFor, Show bundleSizeAssessor) =>
[MakeChangeCriteria minCoinFor bundleSizeAssessor] -> ShowS
forall minCoinFor bundleSizeAssessor.
(Show minCoinFor, Show bundleSizeAssessor) =>
MakeChangeCriteria minCoinFor bundleSizeAssessor -> String
showList :: [MakeChangeCriteria minCoinFor bundleSizeAssessor] -> ShowS
$cshowList :: forall minCoinFor bundleSizeAssessor.
(Show minCoinFor, Show bundleSizeAssessor) =>
[MakeChangeCriteria minCoinFor bundleSizeAssessor] -> ShowS
show :: MakeChangeCriteria minCoinFor bundleSizeAssessor -> String
$cshow :: forall minCoinFor bundleSizeAssessor.
(Show minCoinFor, Show bundleSizeAssessor) =>
MakeChangeCriteria minCoinFor bundleSizeAssessor -> String
showsPrec :: Int -> MakeChangeCriteria minCoinFor bundleSizeAssessor -> ShowS
$cshowsPrec :: forall minCoinFor bundleSizeAssessor.
(Show minCoinFor, Show bundleSizeAssessor) =>
Int -> MakeChangeCriteria minCoinFor bundleSizeAssessor -> ShowS
Show)
tokenBundleSizeExceedsLimit :: TokenBundleSizeAssessor -> TokenBundle -> Bool
tokenBundleSizeExceedsLimit :: TokenBundleSizeAssessor -> TokenBundle -> Bool
tokenBundleSizeExceedsLimit (TokenBundleSizeAssessor TokenBundle -> TokenBundleSizeAssessment
assess) TokenBundle
b =
case TokenBundle -> TokenBundleSizeAssessment
assess TokenBundle
b of
TokenBundleSizeAssessment
TokenBundleSizeWithinLimit->
Bool
False
TokenBundleSizeAssessment
TokenBundleSizeExceedsLimit ->
Bool
True
makeChange
:: MakeChangeCriteria (TokenMap -> Coin) TokenBundleSizeAssessor
-> Either UnableToConstructChangeError [TokenBundle]
makeChange :: MakeChangeCriteria (TokenMap -> Coin) TokenBundleSizeAssessor
-> Either UnableToConstructChangeError [TokenBundle]
makeChange MakeChangeCriteria (TokenMap -> Coin) TokenBundleSizeAssessor
criteria
| Bool -> Bool
not (TokenBundle
totalOutputValue TokenBundle -> TokenBundle -> Bool
forall a. PartialOrd a => a -> a -> Bool
`leq` TokenBundle
totalInputValue) =
Either UnableToConstructChangeError [TokenBundle]
forall a. a
totalInputValueInsufficient
| TokenBundle -> Coin
TokenBundle.getCoin TokenBundle
totalOutputValue Coin -> Coin -> Bool
forall a. Eq a => a -> a -> Bool
== Natural -> Coin
Coin Natural
0 =
Either UnableToConstructChangeError [TokenBundle]
forall a. a
totalOutputCoinValueIsZero
| Bool
otherwise =
(Coin -> UnableToConstructChangeError)
-> Either Coin [TokenBundle]
-> Either UnableToConstructChangeError [TokenBundle]
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Coin -> UnableToConstructChangeError
mkUnableToConstructChangeError (Either Coin [TokenBundle]
-> Either UnableToConstructChangeError [TokenBundle])
-> Either Coin [TokenBundle]
-> Either UnableToConstructChangeError [TokenBundle]
forall a b. (a -> b) -> a -> b
$ do
Coin
adaAvailable <- Coin -> Maybe Coin -> Either Coin Coin
forall a b. a -> Maybe b -> Either a b
maybeToEither
(Coin
requiredCost Coin -> Coin -> Coin
`Coin.difference` Coin
excessCoin)
(Coin
excessCoin Coin -> Coin -> Maybe Coin
`Coin.subtract` Coin
requiredCost)
HasCallStack =>
Coin
-> (TokenMap -> Coin)
-> NonEmpty (TokenMap, Coin)
-> Either Coin [TokenBundle]
Coin
-> (TokenMap -> Coin)
-> NonEmpty (TokenMap, Coin)
-> Either Coin [TokenBundle]
assignCoinsToChangeMaps
Coin
adaAvailable TokenMap -> Coin
minCoinFor NonEmpty (TokenMap, Coin)
changeMapOutputCoinPairs
where
MakeChangeCriteria
{ TokenMap -> Coin
minCoinFor :: TokenMap -> Coin
$sel:minCoinFor:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor -> minCoinFor
minCoinFor
, TokenBundleSizeAssessor
bundleSizeAssessor :: TokenBundleSizeAssessor
$sel:bundleSizeAssessor:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> bundleSizeAssessor
bundleSizeAssessor
, Coin
requiredCost :: Coin
$sel:requiredCost:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor -> Coin
requiredCost
, Coin
extraCoinSource :: Coin
$sel:extraCoinSource:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor -> Coin
extraCoinSource
, Coin
extraCoinSink :: Coin
$sel:extraCoinSink:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor -> Coin
extraCoinSink
, NonEmpty TokenBundle
inputBundles :: NonEmpty TokenBundle
$sel:inputBundles:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> NonEmpty TokenBundle
inputBundles
, NonEmpty TokenBundle
outputBundles :: NonEmpty TokenBundle
$sel:outputBundles:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor
-> NonEmpty TokenBundle
outputBundles
, TokenMap
assetsToMint :: TokenMap
$sel:assetsToMint:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor -> TokenMap
assetsToMint
, TokenMap
assetsToBurn :: TokenMap
$sel:assetsToBurn:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor -> TokenMap
assetsToBurn
, Coin
maximumOutputAdaQuantity :: Coin
$sel:maximumOutputAdaQuantity:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor -> Coin
maximumOutputAdaQuantity
, TokenQuantity
maximumOutputTokenQuantity :: TokenQuantity
$sel:maximumOutputTokenQuantity:MakeChangeCriteria :: forall minCoinFor bundleSizeAssessor.
MakeChangeCriteria minCoinFor bundleSizeAssessor -> TokenQuantity
maximumOutputTokenQuantity
} = MakeChangeCriteria (TokenMap -> Coin) TokenBundleSizeAssessor
criteria
excess :: TokenBundle
excess :: TokenBundle
excess = TokenBundle
totalInputValue TokenBundle -> TokenBundle -> TokenBundle
`TokenBundle.unsafeSubtract` TokenBundle
totalOutputValue
(Coin
excessCoin, [(AssetId, TokenQuantity)]
excessAssets) = TokenBundle -> (Coin, [(AssetId, TokenQuantity)])
TokenBundle.toFlatList TokenBundle
excess
changeMapOutputCoinPairs :: NonEmpty (TokenMap, Coin)
changeMapOutputCoinPairs :: NonEmpty (TokenMap, Coin)
changeMapOutputCoinPairs = NonEmpty Coin
outputCoins
NonEmpty Coin
-> (NonEmpty Coin -> NonEmpty (TokenMap, Coin))
-> NonEmpty (TokenMap, Coin)
forall a b. a -> (a -> b) -> b
& NonEmpty TokenMap -> NonEmpty Coin -> NonEmpty (TokenMap, Coin)
forall a b. NonEmpty a -> NonEmpty b -> NonEmpty (a, b)
NE.zip NonEmpty TokenMap
changeForUserSpecifiedAssets
NonEmpty (TokenMap, Coin)
-> (NonEmpty (TokenMap, Coin) -> NonEmpty (TokenMap, Coin))
-> NonEmpty (TokenMap, Coin)
forall a b. a -> (a -> b) -> b
& ((TokenMap, Coin) -> AssetCount TokenMap)
-> NonEmpty (TokenMap, Coin) -> NonEmpty (TokenMap, Coin)
forall o a. Ord o => (a -> o) -> NonEmpty a -> NonEmpty a
NE.sortWith (TokenMap -> AssetCount TokenMap
forall a. a -> AssetCount a
AssetCount (TokenMap -> AssetCount TokenMap)
-> ((TokenMap, Coin) -> TokenMap)
-> (TokenMap, Coin)
-> AssetCount TokenMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TokenMap, Coin) -> TokenMap
forall a b. (a, b) -> a
fst)
NonEmpty (TokenMap, Coin)
-> (NonEmpty (TokenMap, Coin) -> NonEmpty (TokenMap, Coin))
-> NonEmpty (TokenMap, Coin)
forall a b. a -> (a -> b) -> b
& (TokenMap -> (TokenMap, Coin) -> (TokenMap, Coin))
-> NonEmpty TokenMap
-> NonEmpty (TokenMap, Coin)
-> NonEmpty (TokenMap, Coin)
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NE.zipWith (\TokenMap
m1 (TokenMap
m2, Coin
c) -> (TokenMap
m1 TokenMap -> TokenMap -> TokenMap
forall a. Semigroup a => a -> a -> a
<> TokenMap
m2, Coin
c))
NonEmpty TokenMap
changeForNonUserSpecifiedAssets
NonEmpty (TokenMap, Coin)
-> (NonEmpty (TokenMap, Coin) -> NonEmpty (TokenMap, Coin))
-> NonEmpty (TokenMap, Coin)
forall a b. a -> (a -> b) -> b
& NonEmpty (TokenMap, Coin) -> NonEmpty (TokenMap, Coin)
splitOversizedMaps
where
splitOversizedMaps
:: NonEmpty (TokenMap, Coin) -> NonEmpty (TokenMap, Coin)
splitOversizedMaps :: NonEmpty (TokenMap, Coin) -> NonEmpty (TokenMap, Coin)
splitOversizedMaps =
(TokenBundle -> (TokenMap, Coin))
-> NonEmpty TokenBundle -> NonEmpty (TokenMap, Coin)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TokenBundle -> (TokenMap, Coin)
unbundle (NonEmpty TokenBundle -> NonEmpty (TokenMap, Coin))
-> (NonEmpty (TokenMap, Coin) -> NonEmpty TokenBundle)
-> NonEmpty (TokenMap, Coin)
-> NonEmpty (TokenMap, Coin)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty TokenBundle -> NonEmpty TokenBundle
split (NonEmpty TokenBundle -> NonEmpty TokenBundle)
-> (NonEmpty (TokenMap, Coin) -> NonEmpty TokenBundle)
-> NonEmpty (TokenMap, Coin)
-> NonEmpty TokenBundle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((TokenMap, Coin) -> TokenBundle)
-> NonEmpty (TokenMap, Coin) -> NonEmpty TokenBundle
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TokenMap, Coin) -> TokenBundle
bundle
where
bundle :: (TokenMap, Coin) -> TokenBundle
bundle (TokenMap
m, Coin
c) = Coin -> TokenMap -> TokenBundle
TokenBundle Coin
c TokenMap
m
unbundle :: TokenBundle -> (TokenMap, Coin)
unbundle (TokenBundle Coin
c TokenMap
m) = (TokenMap
m, Coin
c)
split :: NonEmpty TokenBundle -> NonEmpty TokenBundle
split NonEmpty TokenBundle
b = NonEmpty TokenBundle
b
NonEmpty TokenBundle
-> (NonEmpty TokenBundle -> NonEmpty TokenBundle)
-> NonEmpty TokenBundle
forall a b. a -> (a -> b) -> b
& (NonEmpty TokenBundle
-> (TokenBundle -> Bool) -> NonEmpty TokenBundle)
-> (TokenBundle -> Bool)
-> NonEmpty TokenBundle
-> NonEmpty TokenBundle
forall a b c. (a -> b -> c) -> b -> a -> c
flip NonEmpty TokenBundle
-> (TokenBundle -> Bool) -> NonEmpty TokenBundle
splitBundlesWithExcessiveAssetCounts
(TokenBundleSizeAssessor -> TokenBundle -> Bool
tokenBundleSizeExceedsLimit TokenBundleSizeAssessor
assessBundleSizeWithMaxCoin)
NonEmpty TokenBundle
-> (NonEmpty TokenBundle -> NonEmpty TokenBundle)
-> NonEmpty TokenBundle
forall a b. a -> (a -> b) -> b
& (NonEmpty TokenBundle -> TokenQuantity -> NonEmpty TokenBundle)
-> TokenQuantity -> NonEmpty TokenBundle -> NonEmpty TokenBundle
forall a b c. (a -> b -> c) -> b -> a -> c
flip NonEmpty TokenBundle -> TokenQuantity -> NonEmpty TokenBundle
splitBundlesWithExcessiveTokenQuantities
TokenQuantity
maximumOutputTokenQuantity
assessBundleSizeWithMaxCoin :: TokenBundleSizeAssessor
assessBundleSizeWithMaxCoin :: TokenBundleSizeAssessor
assessBundleSizeWithMaxCoin = (TokenBundle -> TokenBundleSizeAssessment)
-> TokenBundleSizeAssessor
TokenBundleSizeAssessor
((TokenBundle -> TokenBundleSizeAssessment)
-> TokenBundleSizeAssessor)
-> (TokenBundle -> TokenBundleSizeAssessment)
-> TokenBundleSizeAssessor
forall a b. (a -> b) -> a -> b
$ (((TokenBundle -> TokenBundleSizeAssessment)
-> Const
(TokenBundle -> TokenBundleSizeAssessment)
(TokenBundle -> TokenBundleSizeAssessment))
-> TokenBundleSizeAssessor
-> Const
(TokenBundle -> TokenBundleSizeAssessment) TokenBundleSizeAssessor)
-> TokenBundleSizeAssessor
-> TokenBundle
-> TokenBundleSizeAssessment
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"assessTokenBundleSize"
(((TokenBundle -> TokenBundleSizeAssessment)
-> Const
(TokenBundle -> TokenBundleSizeAssessment)
(TokenBundle -> TokenBundleSizeAssessment))
-> TokenBundleSizeAssessor
-> Const
(TokenBundle -> TokenBundleSizeAssessment) TokenBundleSizeAssessor)
((TokenBundle -> TokenBundleSizeAssessment)
-> Const
(TokenBundle -> TokenBundleSizeAssessment)
(TokenBundle -> TokenBundleSizeAssessment))
-> TokenBundleSizeAssessor
-> Const
(TokenBundle -> TokenBundleSizeAssessment) TokenBundleSizeAssessor
#assessTokenBundleSize TokenBundleSizeAssessor
bundleSizeAssessor
(TokenBundle -> TokenBundleSizeAssessment)
-> (TokenBundle -> TokenBundle)
-> TokenBundle
-> TokenBundleSizeAssessment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TokenBundle -> Coin -> TokenBundle)
-> Coin -> TokenBundle -> TokenBundle
forall a b c. (a -> b -> c) -> b -> a -> c
flip TokenBundle -> Coin -> TokenBundle
TokenBundle.setCoin Coin
maximumOutputAdaQuantity
changeForUserSpecifiedAssets :: NonEmpty TokenMap
changeForUserSpecifiedAssets :: NonEmpty TokenMap
changeForUserSpecifiedAssets = ((AssetId, TokenQuantity)
-> NonEmpty TokenMap -> NonEmpty TokenMap)
-> NonEmpty TokenMap
-> [(AssetId, TokenQuantity)]
-> NonEmpty TokenMap
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr
((TokenMap -> TokenMap -> TokenMap)
-> NonEmpty TokenMap -> NonEmpty TokenMap -> NonEmpty TokenMap
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NE.zipWith TokenMap -> TokenMap -> TokenMap
forall a. Semigroup a => a -> a -> a
(<>)
(NonEmpty TokenMap -> NonEmpty TokenMap -> NonEmpty TokenMap)
-> ((AssetId, TokenQuantity) -> NonEmpty TokenMap)
-> (AssetId, TokenQuantity)
-> NonEmpty TokenMap
-> NonEmpty TokenMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty TokenMap -> (AssetId, TokenQuantity) -> NonEmpty TokenMap
makeChangeForUserSpecifiedAsset NonEmpty TokenMap
outputMaps)
(TokenMap
TokenMap.empty TokenMap -> NonEmpty TokenMap -> NonEmpty TokenMap
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ NonEmpty TokenMap
outputMaps)
[(AssetId, TokenQuantity)]
excessAssets
changeForNonUserSpecifiedAssets :: NonEmpty TokenMap
changeForNonUserSpecifiedAssets :: NonEmpty TokenMap
changeForNonUserSpecifiedAssets =
NonEmpty TokenMap
-> Map AssetId (NonEmpty TokenQuantity) -> NonEmpty TokenMap
forall a.
NonEmpty a
-> Map AssetId (NonEmpty TokenQuantity) -> NonEmpty TokenMap
makeChangeForNonUserSpecifiedAssets
NonEmpty TokenMap
outputMaps
Map AssetId (NonEmpty TokenQuantity)
nonUserSpecifiedAssetQuantities
NonEmpty TokenMap
-> (NonEmpty TokenMap -> NonEmpty TokenMap) -> NonEmpty TokenMap
forall a b. a -> (a -> b) -> b
& TokenMap -> NonEmpty TokenMap -> NonEmpty TokenMap
addMintValuesToChangeMaps
(TokenMap -> TokenMap
removeUserSpecifiedAssetIds TokenMap
assetsToMint)
NonEmpty TokenMap
-> (NonEmpty TokenMap -> NonEmpty TokenMap) -> NonEmpty TokenMap
forall a b. a -> (a -> b) -> b
& TokenMap -> NonEmpty TokenMap -> NonEmpty TokenMap
removeBurnValuesFromChangeMaps
(TokenMap -> TokenMap
removeUserSpecifiedAssetIds TokenMap
assetsToBurn)
where
removeUserSpecifiedAssetIds :: TokenMap -> TokenMap
removeUserSpecifiedAssetIds :: TokenMap -> TokenMap
removeUserSpecifiedAssetIds =
(AssetId -> Bool) -> TokenMap -> TokenMap
TokenMap.filter (AssetId -> Set AssetId -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.notMember` Set AssetId
userSpecifiedAssetIds)
totalInputValueInsufficient :: a
totalInputValueInsufficient = String -> a
forall a. HasCallStack => String -> a
error
String
"makeChange: not (totalOutputValue <= totalInputValue)"
totalOutputCoinValueIsZero :: a
totalOutputCoinValueIsZero = String -> a
forall a. HasCallStack => String -> a
error
String
"makeChange: not (totalOutputCoinValue > 0)"
mkUnableToConstructChangeError :: Coin -> UnableToConstructChangeError
mkUnableToConstructChangeError :: Coin -> UnableToConstructChangeError
mkUnableToConstructChangeError Coin
shortfall = UnableToConstructChangeError :: Coin -> Coin -> UnableToConstructChangeError
UnableToConstructChangeError
{ Coin
requiredCost :: Coin
$sel:requiredCost:UnableToConstructChangeError :: Coin
requiredCost
, Coin
shortfall :: Coin
$sel:shortfall:UnableToConstructChangeError :: Coin
shortfall
}
outputMaps :: NonEmpty TokenMap
outputMaps :: NonEmpty TokenMap
outputMaps = ((TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle)
-> TokenBundle -> TokenMap
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"tokens"
((TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle)
(TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle
#tokens (TokenBundle -> TokenMap)
-> NonEmpty TokenBundle -> NonEmpty TokenMap
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty TokenBundle
outputBundles
outputCoins :: NonEmpty Coin
outputCoins :: NonEmpty Coin
outputCoins = ((Coin -> Const Coin Coin)
-> TokenBundle -> Const Coin TokenBundle)
-> TokenBundle -> Coin
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"coin"
((Coin -> Const Coin Coin)
-> TokenBundle -> Const Coin TokenBundle)
(Coin -> Const Coin Coin) -> TokenBundle -> Const Coin TokenBundle
#coin (TokenBundle -> Coin) -> NonEmpty TokenBundle -> NonEmpty Coin
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty TokenBundle
outputBundles
totalInputValue :: TokenBundle
totalInputValue :: TokenBundle
totalInputValue =
NonEmpty TokenBundle -> TokenBundle
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
F.fold NonEmpty TokenBundle
inputBundles
TokenBundle -> TokenBundle -> TokenBundle
forall a. Semigroup a => a -> a -> a
<> Coin -> TokenBundle
TokenBundle.fromCoin Coin
extraCoinSource
TokenBundle -> TokenBundle -> TokenBundle
forall a. Semigroup a => a -> a -> a
<> TokenMap -> TokenBundle
TokenBundle.fromTokenMap TokenMap
assetsToMint
totalOutputValue :: TokenBundle
totalOutputValue :: TokenBundle
totalOutputValue =
NonEmpty TokenBundle -> TokenBundle
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
F.fold NonEmpty TokenBundle
outputBundles
TokenBundle -> TokenBundle -> TokenBundle
forall a. Semigroup a => a -> a -> a
<> Coin -> TokenBundle
TokenBundle.fromCoin Coin
extraCoinSink
TokenBundle -> TokenBundle -> TokenBundle
forall a. Semigroup a => a -> a -> a
<> TokenMap -> TokenBundle
TokenBundle.fromTokenMap TokenMap
assetsToBurn
userSpecifiedAssetIds :: Set AssetId
userSpecifiedAssetIds :: Set AssetId
userSpecifiedAssetIds = TokenBundle -> Set AssetId
TokenBundle.getAssets (NonEmpty TokenBundle -> TokenBundle
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
F.fold NonEmpty TokenBundle
outputBundles)
nonUserSpecifiedAssetQuantities :: Map AssetId (NonEmpty TokenQuantity)
nonUserSpecifiedAssetQuantities :: Map AssetId (NonEmpty TokenQuantity)
nonUserSpecifiedAssetQuantities =
NonEmpty TokenMap
-> Set AssetId -> Map AssetId (NonEmpty TokenQuantity)
collateNonUserSpecifiedAssetQuantities
(((TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle)
-> TokenBundle -> TokenMap
forall a s. ((a -> Const a a) -> s -> Const a s) -> s -> a
view IsLabel
"tokens"
((TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle)
(TokenMap -> Const TokenMap TokenMap)
-> TokenBundle -> Const TokenMap TokenBundle
#tokens (TokenBundle -> TokenMap)
-> NonEmpty TokenBundle -> NonEmpty TokenMap
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty TokenBundle
inputBundles) Set AssetId
userSpecifiedAssetIds
collateNonUserSpecifiedAssetQuantities
:: NonEmpty TokenMap
-> Set AssetId
-> Map AssetId (NonEmpty TokenQuantity)
collateNonUserSpecifiedAssetQuantities :: NonEmpty TokenMap
-> Set AssetId -> Map AssetId (NonEmpty TokenQuantity)
collateNonUserSpecifiedAssetQuantities NonEmpty TokenMap
inputMaps Set AssetId
userSpecifiedAssetIds =
(TokenMap
-> Map AssetId (NonEmpty TokenQuantity)
-> Map AssetId (NonEmpty TokenQuantity))
-> Map AssetId (NonEmpty TokenQuantity)
-> NonEmpty TokenMap
-> Map AssetId (NonEmpty TokenQuantity)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr TokenMap
-> Map AssetId (NonEmpty TokenQuantity)
-> Map AssetId (NonEmpty TokenQuantity)
discardUserSpecifiedAssets Map AssetId (NonEmpty TokenQuantity)
forall a. Monoid a => a
mempty NonEmpty TokenMap
inputMaps
where
discardUserSpecifiedAssets
:: TokenMap
-> Map AssetId (NonEmpty TokenQuantity)
-> Map AssetId (NonEmpty TokenQuantity)
discardUserSpecifiedAssets :: TokenMap
-> Map AssetId (NonEmpty TokenQuantity)
-> Map AssetId (NonEmpty TokenQuantity)
discardUserSpecifiedAssets TokenMap
tokens Map AssetId (NonEmpty TokenQuantity)
m =
((AssetId, TokenQuantity)
-> Map AssetId (NonEmpty TokenQuantity)
-> Map AssetId (NonEmpty TokenQuantity))
-> Map AssetId (NonEmpty TokenQuantity)
-> [(AssetId, TokenQuantity)]
-> Map AssetId (NonEmpty TokenQuantity)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(AssetId
k, TokenQuantity
v) -> (NonEmpty TokenQuantity
-> NonEmpty TokenQuantity -> NonEmpty TokenQuantity)
-> AssetId
-> NonEmpty TokenQuantity
-> Map AssetId (NonEmpty TokenQuantity)
-> Map AssetId (NonEmpty TokenQuantity)
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith NonEmpty TokenQuantity
-> NonEmpty TokenQuantity -> NonEmpty TokenQuantity
forall a. Semigroup a => a -> a -> a
(<>) AssetId
k (TokenQuantity
v TokenQuantity -> [TokenQuantity] -> NonEmpty TokenQuantity
forall a. a -> [a] -> NonEmpty a
:| [])) Map AssetId (NonEmpty TokenQuantity)
m [(AssetId, TokenQuantity)]
filtered
where
filtered :: [(AssetId, TokenQuantity)]
filtered = ((AssetId, TokenQuantity) -> Bool)
-> [(AssetId, TokenQuantity)] -> [(AssetId, TokenQuantity)]
forall a. (a -> Bool) -> [a] -> [a]
filter
((AssetId -> Set AssetId -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.notMember` Set AssetId
userSpecifiedAssetIds) (AssetId -> Bool)
-> ((AssetId, TokenQuantity) -> AssetId)
-> (AssetId, TokenQuantity)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AssetId, TokenQuantity) -> AssetId
forall a b. (a, b) -> a
fst)
(TokenMap -> [(AssetId, TokenQuantity)]
TokenMap.toFlatList TokenMap
tokens)
assignCoinsToChangeMaps
:: HasCallStack
=> Coin
-> (TokenMap -> Coin)
-> NonEmpty (TokenMap, Coin)
-> Either Coin [TokenBundle]
assignCoinsToChangeMaps :: Coin
-> (TokenMap -> Coin)
-> NonEmpty (TokenMap, Coin)
-> Either Coin [TokenBundle]
assignCoinsToChangeMaps Coin
adaAvailable TokenMap -> Coin
minCoinFor NonEmpty (TokenMap, Coin)
pairsAtStart
| Bool -> Bool
not Bool
changeMapsCorrectlyOrdered =
Either Coin [TokenBundle]
forall a. a
changeMapsNotCorrectlyOrderedError
| Bool
otherwise =
Coin -> NonEmpty (TokenMap, Coin) -> Either Coin [TokenBundle]
loop Coin
adaRequiredAtStart NonEmpty (TokenMap, Coin)
pairsAtStart
where
loop :: Coin -> NonEmpty (TokenMap, Coin) -> Either Coin [TokenBundle]
loop !Coin
adaRequired !NonEmpty (TokenMap, Coin)
pairsNonEmpty = case NonEmpty (TokenMap, Coin)
pairsNonEmpty of
(TokenMap, Coin)
pair :| [(TokenMap, Coin)]
pairs | Coin
adaAvailable Coin -> Coin -> Bool
forall a. Ord a => a -> a -> Bool
>= Coin
adaRequired ->
let assetMapsRemaining :: NonEmpty TokenMap
assetMapsRemaining = (TokenMap, Coin) -> TokenMap
forall a b. (a, b) -> a
fst ((TokenMap, Coin) -> TokenMap)
-> NonEmpty (TokenMap, Coin) -> NonEmpty TokenMap
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((TokenMap, Coin)
pair (TokenMap, Coin) -> [(TokenMap, Coin)] -> NonEmpty (TokenMap, Coin)
forall a. a -> [a] -> NonEmpty a
:| [(TokenMap, Coin)]
pairs) in
let bundlesForAssetsWithMinimumCoins :: NonEmpty TokenBundle
bundlesForAssetsWithMinimumCoins =
(TokenMap -> Coin) -> TokenMap -> TokenBundle
assignMinimumCoin TokenMap -> Coin
minCoinFor (TokenMap -> TokenBundle)
-> NonEmpty TokenMap -> NonEmpty TokenBundle
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty TokenMap
assetMapsRemaining in
let adaRemaining :: Coin
adaRemaining = Coin
adaAvailable Coin -> Coin -> Coin
`Coin.distance` Coin
adaRequired in
let outputCoinsRemaining :: NonEmpty Coin
outputCoinsRemaining = (TokenMap, Coin) -> Coin
forall a b. (a, b) -> b
snd ((TokenMap, Coin) -> Coin)
-> NonEmpty (TokenMap, Coin) -> NonEmpty Coin
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((TokenMap, Coin)
pair (TokenMap, Coin) -> [(TokenMap, Coin)] -> NonEmpty (TokenMap, Coin)
forall a. a -> [a] -> NonEmpty a
:| [(TokenMap, Coin)]
pairs) in
let bundlesForOutputCoins :: NonEmpty TokenBundle
bundlesForOutputCoins = Coin -> TokenBundle
TokenBundle.fromCoin (Coin -> TokenBundle) -> NonEmpty Coin -> NonEmpty TokenBundle
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
HasCallStack => NonEmpty Coin -> Coin -> NonEmpty Coin
NonEmpty Coin -> Coin -> NonEmpty Coin
makeChangeForCoin NonEmpty Coin
outputCoinsRemaining Coin
adaRemaining in
[TokenBundle] -> Either Coin [TokenBundle]
forall a b. b -> Either a b
Right ([TokenBundle] -> Either Coin [TokenBundle])
-> [TokenBundle] -> Either Coin [TokenBundle]
forall a b. (a -> b) -> a -> b
$ NonEmpty TokenBundle -> [TokenBundle]
forall a. NonEmpty a -> [a]
NE.toList (NonEmpty TokenBundle -> [TokenBundle])
-> NonEmpty TokenBundle -> [TokenBundle]
forall a b. (a -> b) -> a -> b
$ (TokenBundle -> TokenBundle -> TokenBundle)
-> NonEmpty TokenBundle
-> NonEmpty TokenBundle
-> NonEmpty TokenBundle
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NE.zipWith TokenBundle -> TokenBundle -> TokenBundle
forall a. Semigroup a => a -> a -> a
(<>)
NonEmpty TokenBundle
bundlesForAssetsWithMinimumCoins
NonEmpty TokenBundle
bundlesForOutputCoins
(TokenMap
m, Coin
_) :| ((TokenMap, Coin)
p : [(TokenMap, Coin)]
ps) | TokenMap -> Bool
TokenMap.isEmpty TokenMap
m Bool -> Bool -> Bool
&& Coin
adaAvailable Coin -> Coin -> Bool
forall a. Ord a => a -> a -> Bool
< Coin
adaRequired ->
let adaRequired' :: Coin
adaRequired' = Coin
adaRequired Coin -> Coin -> Coin
`Coin.distance` TokenMap -> Coin
minCoinFor TokenMap
m in
Coin -> NonEmpty (TokenMap, Coin) -> Either Coin [TokenBundle]
loop Coin
adaRequired' ((TokenMap, Coin)
p (TokenMap, Coin) -> [(TokenMap, Coin)] -> NonEmpty (TokenMap, Coin)
forall a. a -> [a] -> NonEmpty a
:| [(TokenMap, Coin)]
ps)
(TokenMap
m, Coin
_) :| [] | TokenMap -> Bool
TokenMap.isEmpty TokenMap
m Bool -> Bool -> Bool
&& Coin
adaAvailable Coin -> Coin -> Bool
forall a. Ord a => a -> a -> Bool
< Coin
adaRequired ->
[TokenBundle] -> Either Coin [TokenBundle]
forall a b. b -> Either a b
Right []
NonEmpty (TokenMap, Coin)
_ ->
Coin -> Either Coin [TokenBundle]
forall a b. a -> Either a b
Left (Coin
adaRequired Coin -> Coin -> Coin
`Coin.difference` Coin
adaAvailable)
adaRequiredAtStart :: Coin
adaRequiredAtStart = NonEmpty Coin -> Coin
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
F.fold (NonEmpty Coin -> Coin) -> NonEmpty Coin -> Coin
forall a b. (a -> b) -> a -> b
$ TokenMap -> Coin
minCoinFor (TokenMap -> Coin)
-> ((TokenMap, Coin) -> TokenMap) -> (TokenMap, Coin) -> Coin
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TokenMap, Coin) -> TokenMap
forall a b. (a, b) -> a
fst ((TokenMap, Coin) -> Coin)
-> NonEmpty (TokenMap, Coin) -> NonEmpty Coin
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (TokenMap, Coin)
pairsAtStart
changeMaps :: NonEmpty TokenMap
changeMaps = (TokenMap, Coin) -> TokenMap
forall a b. (a, b) -> a
fst ((TokenMap, Coin) -> TokenMap)
-> NonEmpty (TokenMap, Coin) -> NonEmpty TokenMap
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (TokenMap, Coin)
pairsAtStart
changeMapsCorrectlyOrdered :: Bool
changeMapsCorrectlyOrdered = [TokenMap] -> [TokenMap] -> Bool
forall a. Eq a => a -> a -> Bool
(==)
((TokenMap -> Bool) -> NonEmpty TokenMap -> [TokenMap]
forall a. (a -> Bool) -> NonEmpty a -> [a]
NE.takeWhile TokenMap -> Bool
TokenMap.isEmpty NonEmpty TokenMap
changeMaps)
((TokenMap -> Bool) -> NonEmpty TokenMap -> [TokenMap]
forall a. (a -> Bool) -> NonEmpty a -> [a]
NE.filter TokenMap -> Bool
TokenMap.isEmpty NonEmpty TokenMap
changeMaps)
changeMapsNotCorrectlyOrderedError :: a
changeMapsNotCorrectlyOrderedError =
String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
[ Item [String]
"assignCoinsToChangeMaps: pre-computed asset change maps must be"
, Item [String]
"arranged in an order where all empty maps are at the start of"
, Item [String]
"the list."
]
assignMinimumCoin :: (TokenMap -> Coin) -> TokenMap -> TokenBundle
assignMinimumCoin :: (TokenMap -> Coin) -> TokenMap -> TokenBundle
assignMinimumCoin TokenMap -> Coin
minCoinFor TokenMap
m = Coin -> TokenMap -> TokenBundle
TokenBundle (TokenMap -> Coin
minCoinFor TokenMap
m) TokenMap
m
makeChangeForUserSpecifiedAsset
:: NonEmpty TokenMap
-> (AssetId, TokenQuantity)
-> NonEmpty TokenMap
makeChangeForUserSpecifiedAsset :: NonEmpty TokenMap -> (AssetId, TokenQuantity) -> NonEmpty TokenMap
makeChangeForUserSpecifiedAsset NonEmpty TokenMap
targets (AssetId
asset, TokenQuantity
excess) =
AssetId -> TokenQuantity -> TokenMap
TokenMap.singleton AssetId
asset (TokenQuantity -> TokenMap)
-> NonEmpty TokenQuantity -> NonEmpty TokenMap
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
NonEmpty TokenQuantity
-> Maybe (NonEmpty TokenQuantity) -> NonEmpty TokenQuantity
forall a. a -> Maybe a -> a
fromMaybe NonEmpty TokenQuantity
zeros (TokenQuantity
-> NonEmpty TokenQuantity -> Maybe (NonEmpty TokenQuantity)
TokenQuantity.partition TokenQuantity
excess NonEmpty TokenQuantity
weights)
where
weights :: NonEmpty TokenQuantity
weights :: NonEmpty TokenQuantity
weights = (TokenMap -> AssetId -> TokenQuantity)
-> AssetId -> TokenMap -> TokenQuantity
forall a b c. (a -> b -> c) -> b -> a -> c
flip TokenMap -> AssetId -> TokenQuantity
TokenMap.getQuantity AssetId
asset (TokenMap -> TokenQuantity)
-> NonEmpty TokenMap -> NonEmpty TokenQuantity
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty TokenMap
targets
zeros :: NonEmpty TokenQuantity
zeros :: NonEmpty TokenQuantity
zeros = Natural -> TokenQuantity
TokenQuantity Natural
0 TokenQuantity -> NonEmpty TokenMap -> NonEmpty TokenQuantity
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ NonEmpty TokenMap
targets
makeChangeForNonUserSpecifiedAsset
:: NonEmpty a
-> (AssetId, NonEmpty TokenQuantity)
-> NonEmpty TokenMap
makeChangeForNonUserSpecifiedAsset :: NonEmpty a
-> (AssetId, NonEmpty TokenQuantity) -> NonEmpty TokenMap
makeChangeForNonUserSpecifiedAsset NonEmpty a
n (AssetId
asset, NonEmpty TokenQuantity
quantities) =
AssetId -> TokenQuantity -> TokenMap
TokenMap.singleton AssetId
asset (TokenQuantity -> TokenMap)
-> NonEmpty TokenQuantity -> NonEmpty TokenMap
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty TokenQuantity -> NonEmpty a -> NonEmpty TokenQuantity
forall m a.
(Monoid m, Ord m) =>
NonEmpty m -> NonEmpty a -> NonEmpty m
padCoalesce NonEmpty TokenQuantity
quantities NonEmpty a
n
makeChangeForNonUserSpecifiedAssets
:: NonEmpty a
-> Map AssetId (NonEmpty TokenQuantity)
-> NonEmpty TokenMap
makeChangeForNonUserSpecifiedAssets :: NonEmpty a
-> Map AssetId (NonEmpty TokenQuantity) -> NonEmpty TokenMap
makeChangeForNonUserSpecifiedAssets NonEmpty a
n Map AssetId (NonEmpty TokenQuantity)
nonUserSpecifiedAssetQuantities =
((AssetId, NonEmpty TokenQuantity)
-> NonEmpty TokenMap -> NonEmpty TokenMap)
-> NonEmpty TokenMap
-> [(AssetId, NonEmpty TokenQuantity)]
-> NonEmpty TokenMap
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr
((TokenMap -> TokenMap -> TokenMap)
-> NonEmpty TokenMap -> NonEmpty TokenMap -> NonEmpty TokenMap
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NE.zipWith TokenMap -> TokenMap -> TokenMap
forall a. Semigroup a => a -> a -> a
(<>) (NonEmpty TokenMap -> NonEmpty TokenMap -> NonEmpty TokenMap)
-> ((AssetId, NonEmpty TokenQuantity) -> NonEmpty TokenMap)
-> (AssetId, NonEmpty TokenQuantity)
-> NonEmpty TokenMap
-> NonEmpty TokenMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a
-> (AssetId, NonEmpty TokenQuantity) -> NonEmpty TokenMap
forall a.
NonEmpty a
-> (AssetId, NonEmpty TokenQuantity) -> NonEmpty TokenMap
makeChangeForNonUserSpecifiedAsset NonEmpty a
n)
(TokenMap
TokenMap.empty TokenMap -> NonEmpty a -> NonEmpty TokenMap
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ NonEmpty a
n)
(Map AssetId (NonEmpty TokenQuantity)
-> [(AssetId, NonEmpty TokenQuantity)]
forall k a. Map k a -> [(k, a)]
Map.toList Map AssetId (NonEmpty TokenQuantity)
nonUserSpecifiedAssetQuantities)
makeChangeForCoin
:: HasCallStack
=> NonEmpty Coin
-> Coin
-> NonEmpty Coin
makeChangeForCoin :: NonEmpty Coin -> Coin -> NonEmpty Coin
makeChangeForCoin = (Coin -> NonEmpty Coin -> NonEmpty Coin)
-> NonEmpty Coin -> Coin -> NonEmpty Coin
forall a b c. (a -> b -> c) -> b -> a -> c
flip HasCallStack => Coin -> NonEmpty Coin -> NonEmpty Coin
Coin -> NonEmpty Coin -> NonEmpty Coin
Coin.unsafePartition
addMintValueToChangeMaps
:: (AssetId, TokenQuantity)
-> NonEmpty TokenMap
-> NonEmpty TokenMap
addMintValueToChangeMaps :: (AssetId, TokenQuantity) -> NonEmpty TokenMap -> NonEmpty TokenMap
addMintValueToChangeMaps (AssetId
assetId, TokenQuantity
assetQty) =
(TokenMap -> TokenMap) -> NonEmpty TokenMap -> NonEmpty TokenMap
forall a. (a -> a) -> NonEmpty a -> NonEmpty a
modifyLast ((TokenMap -> TokenMap) -> NonEmpty TokenMap -> NonEmpty TokenMap)
-> (TokenMap -> TokenMap) -> NonEmpty TokenMap -> NonEmpty TokenMap
forall a b. (a -> b) -> a -> b
$ \TokenMap
m -> TokenMap -> AssetId -> (TokenQuantity -> TokenQuantity) -> TokenMap
TokenMap.adjustQuantity TokenMap
m AssetId
assetId (TokenQuantity -> TokenQuantity -> TokenQuantity
forall a. Semigroup a => a -> a -> a
<> TokenQuantity
assetQty)
where
modifyLast :: (a -> a) -> NonEmpty a -> NonEmpty a
modifyLast a -> a
f NonEmpty a
xs = case NonEmpty a -> NonEmpty a
forall a. NonEmpty a -> NonEmpty a
NE.reverse NonEmpty a
xs of
(a
y :| [a]
ys) -> NonEmpty a -> NonEmpty a
forall a. NonEmpty a -> NonEmpty a
NE.reverse (a -> a
f a
y a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
ys)
addMintValuesToChangeMaps
:: TokenMap
-> NonEmpty TokenMap
-> NonEmpty TokenMap
addMintValuesToChangeMaps :: TokenMap -> NonEmpty TokenMap -> NonEmpty TokenMap
addMintValuesToChangeMaps =
(NonEmpty TokenMap
-> [(AssetId, TokenQuantity)] -> NonEmpty TokenMap)
-> [(AssetId, TokenQuantity)]
-> NonEmpty TokenMap
-> NonEmpty TokenMap
forall a b c. (a -> b -> c) -> b -> a -> c
flip (((AssetId, TokenQuantity)
-> NonEmpty TokenMap -> NonEmpty TokenMap)
-> NonEmpty TokenMap
-> [(AssetId, TokenQuantity)]
-> NonEmpty TokenMap
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr (AssetId, TokenQuantity) -> NonEmpty TokenMap -> NonEmpty TokenMap
addMintValueToChangeMaps) ([(AssetId, TokenQuantity)]
-> NonEmpty TokenMap -> NonEmpty TokenMap)
-> (TokenMap -> [(AssetId, TokenQuantity)])
-> TokenMap
-> NonEmpty TokenMap
-> NonEmpty TokenMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TokenMap -> [(AssetId, TokenQuantity)]
TokenMap.toFlatList
removeBurnValueFromChangeMaps
:: (AssetId, TokenQuantity)
-> NonEmpty TokenMap
-> NonEmpty TokenMap
removeBurnValueFromChangeMaps :: (AssetId, TokenQuantity) -> NonEmpty TokenMap -> NonEmpty TokenMap
removeBurnValueFromChangeMaps (AssetId
assetId, TokenQuantity
assetQty) NonEmpty TokenMap
maps = NonEmpty TokenMap
maps
NonEmpty TokenMap
-> (NonEmpty TokenMap -> NonEmpty TokenQuantity)
-> NonEmpty TokenQuantity
forall a b. a -> (a -> b) -> b
& (TokenMap -> TokenQuantity)
-> NonEmpty TokenMap -> NonEmpty TokenQuantity
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TokenMap -> AssetId -> TokenQuantity
`TokenMap.getQuantity` AssetId
assetId)
NonEmpty TokenQuantity
-> (NonEmpty TokenQuantity -> NonEmpty TokenQuantity)
-> NonEmpty TokenQuantity
forall a b. a -> (a -> b) -> b
& TokenQuantity -> NonEmpty TokenQuantity -> NonEmpty TokenQuantity
reduceTokenQuantities TokenQuantity
assetQty
NonEmpty TokenQuantity
-> (NonEmpty TokenQuantity -> NonEmpty TokenMap)
-> NonEmpty TokenMap
forall a b. a -> (a -> b) -> b
& (TokenMap -> TokenQuantity -> TokenMap)
-> NonEmpty TokenMap -> NonEmpty TokenQuantity -> NonEmpty TokenMap
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NE.zipWith (TokenMap -> AssetId -> TokenQuantity -> TokenMap
`TokenMap.setQuantity` AssetId
assetId) NonEmpty TokenMap
maps
reduceTokenQuantities
:: TokenQuantity
-> NonEmpty TokenQuantity
-> NonEmpty TokenQuantity
reduceTokenQuantities :: TokenQuantity -> NonEmpty TokenQuantity -> NonEmpty TokenQuantity
reduceTokenQuantities TokenQuantity
reductionTarget NonEmpty TokenQuantity
quantities =
[TokenQuantity] -> NonEmpty TokenQuantity
forall a. [a] -> NonEmpty a
NE.fromList ([TokenQuantity] -> NonEmpty TokenQuantity)
-> [TokenQuantity] -> NonEmpty TokenQuantity
forall a b. (a -> b) -> a -> b
$ TokenQuantity
-> [TokenQuantity] -> [TokenQuantity] -> [TokenQuantity]
burn TokenQuantity
reductionTarget (NonEmpty TokenQuantity -> [TokenQuantity]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty TokenQuantity
quantities) []
where
burn :: TokenQuantity
-> [TokenQuantity] -> [TokenQuantity] -> [TokenQuantity]
burn TokenQuantity
_ [ ] [TokenQuantity]
ys = [TokenQuantity] -> [TokenQuantity]
forall a. [a] -> [a]
reverse [TokenQuantity]
ys
burn TokenQuantity
b (TokenQuantity
x : [TokenQuantity]
xs) [TokenQuantity]
ys
| TokenQuantity
x TokenQuantity -> TokenQuantity -> Bool
forall a. Ord a => a -> a -> Bool
>= TokenQuantity
b = [TokenQuantity] -> [TokenQuantity]
forall a. [a] -> [a]
reverse [TokenQuantity]
ys [TokenQuantity] -> [TokenQuantity] -> [TokenQuantity]
forall a. Semigroup a => a -> a -> a
<> (TokenQuantity
x' TokenQuantity -> [TokenQuantity] -> [TokenQuantity]
forall a. a -> [a] -> [a]
: [TokenQuantity]
xs)
| Bool
otherwise = TokenQuantity
-> [TokenQuantity] -> [TokenQuantity] -> [TokenQuantity]
burn TokenQuantity
b' [TokenQuantity]
xs (TokenQuantity
x' TokenQuantity -> [TokenQuantity] -> [TokenQuantity]
forall a. a -> [a] -> [a]
: [TokenQuantity]
ys)
where
b' :: TokenQuantity
b' = TokenQuantity
b TokenQuantity -> TokenQuantity -> TokenQuantity
`TokenQuantity.difference` TokenQuantity
x
x' :: TokenQuantity
x' = TokenQuantity
x TokenQuantity -> TokenQuantity -> TokenQuantity
`TokenQuantity.difference` TokenQuantity
b
removeBurnValuesFromChangeMaps
:: TokenMap
-> NonEmpty TokenMap
-> NonEmpty TokenMap
removeBurnValuesFromChangeMaps :: TokenMap -> NonEmpty TokenMap -> NonEmpty TokenMap
removeBurnValuesFromChangeMaps =
(NonEmpty TokenMap
-> [(AssetId, TokenQuantity)] -> NonEmpty TokenMap)
-> [(AssetId, TokenQuantity)]
-> NonEmpty TokenMap
-> NonEmpty TokenMap
forall a b c. (a -> b -> c) -> b -> a -> c
flip (((AssetId, TokenQuantity)
-> NonEmpty TokenMap -> NonEmpty TokenMap)
-> NonEmpty TokenMap
-> [(AssetId, TokenQuantity)]
-> NonEmpty TokenMap
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr (AssetId, TokenQuantity) -> NonEmpty TokenMap -> NonEmpty TokenMap
removeBurnValueFromChangeMaps) ([(AssetId, TokenQuantity)]
-> NonEmpty TokenMap -> NonEmpty TokenMap)
-> (TokenMap -> [(AssetId, TokenQuantity)])
-> TokenMap
-> NonEmpty TokenMap
-> NonEmpty TokenMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TokenMap -> [(AssetId, TokenQuantity)]
TokenMap.toFlatList
splitBundleIfAssetCountExcessive
:: TokenBundle
-> (TokenBundle -> Bool)
-> NonEmpty TokenBundle
splitBundleIfAssetCountExcessive :: TokenBundle -> (TokenBundle -> Bool) -> NonEmpty TokenBundle
splitBundleIfAssetCountExcessive TokenBundle
b TokenBundle -> Bool
isExcessive
| TokenBundle -> Bool
isExcessive TokenBundle
b =
TokenBundle -> NonEmpty TokenBundle
splitInHalf TokenBundle
b NonEmpty TokenBundle
-> (TokenBundle -> NonEmpty TokenBundle) -> NonEmpty TokenBundle
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (TokenBundle -> (TokenBundle -> Bool) -> NonEmpty TokenBundle)
-> (TokenBundle -> Bool) -> TokenBundle -> NonEmpty TokenBundle
forall a b c. (a -> b -> c) -> b -> a -> c
flip TokenBundle -> (TokenBundle -> Bool) -> NonEmpty TokenBundle
splitBundleIfAssetCountExcessive TokenBundle -> Bool
isExcessive
| Bool
otherwise =
TokenBundle -> NonEmpty TokenBundle
forall (f :: * -> *) a. Applicative f => a -> f a
pure TokenBundle
b
where
splitInHalf :: TokenBundle -> NonEmpty TokenBundle
splitInHalf = (TokenBundle -> NonEmpty () -> NonEmpty TokenBundle)
-> NonEmpty () -> TokenBundle -> NonEmpty TokenBundle
forall a b c. (a -> b -> c) -> b -> a -> c
flip TokenBundle -> NonEmpty () -> NonEmpty TokenBundle
forall a. TokenBundle -> NonEmpty a -> NonEmpty TokenBundle
TokenBundle.equipartitionAssets (() () -> [()] -> NonEmpty ()
forall a. a -> [a] -> NonEmpty a
:| [()])
splitBundlesWithExcessiveAssetCounts
:: NonEmpty TokenBundle
-> (TokenBundle -> Bool)
-> NonEmpty TokenBundle
splitBundlesWithExcessiveAssetCounts :: NonEmpty TokenBundle
-> (TokenBundle -> Bool) -> NonEmpty TokenBundle
splitBundlesWithExcessiveAssetCounts NonEmpty TokenBundle
bs TokenBundle -> Bool
isExcessive =
(TokenBundle -> (TokenBundle -> Bool) -> NonEmpty TokenBundle
`splitBundleIfAssetCountExcessive` TokenBundle -> Bool
isExcessive) (TokenBundle -> NonEmpty TokenBundle)
-> NonEmpty TokenBundle -> NonEmpty TokenBundle
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NonEmpty TokenBundle
bs
splitBundlesWithExcessiveTokenQuantities
:: NonEmpty TokenBundle
-> TokenQuantity
-> NonEmpty TokenBundle
splitBundlesWithExcessiveTokenQuantities :: NonEmpty TokenBundle -> TokenQuantity -> NonEmpty TokenBundle
splitBundlesWithExcessiveTokenQuantities NonEmpty TokenBundle
bs TokenQuantity
maxQuantity =
(TokenBundle -> TokenQuantity -> NonEmpty TokenBundle
`TokenBundle.equipartitionQuantitiesWithUpperBound` TokenQuantity
maxQuantity) (TokenBundle -> NonEmpty TokenBundle)
-> NonEmpty TokenBundle -> NonEmpty TokenBundle
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NonEmpty TokenBundle
bs
groupByKey :: forall k v. Ord k => [(k, v)] -> Map k (NonEmpty v)
groupByKey :: [(k, v)] -> Map k (NonEmpty v)
groupByKey = (Map k (NonEmpty v) -> (k, v) -> Map k (NonEmpty v))
-> Map k (NonEmpty v) -> [(k, v)] -> Map k (NonEmpty v)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' Map k (NonEmpty v) -> (k, v) -> Map k (NonEmpty v)
acc Map k (NonEmpty v)
forall a. Monoid a => a
mempty
where
acc :: Map k (NonEmpty v) -> (k, v) -> Map k (NonEmpty v)
acc :: Map k (NonEmpty v) -> (k, v) -> Map k (NonEmpty v)
acc Map k (NonEmpty v)
m (k
k, v
v) = (Maybe (NonEmpty v) -> Maybe (NonEmpty v))
-> k -> Map k (NonEmpty v) -> Map k (NonEmpty v)
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
Map.alter (NonEmpty v -> Maybe (NonEmpty v)
forall a. a -> Maybe a
Just (NonEmpty v -> Maybe (NonEmpty v))
-> (Maybe (NonEmpty v) -> NonEmpty v)
-> Maybe (NonEmpty v)
-> Maybe (NonEmpty v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty v
-> (NonEmpty v -> NonEmpty v) -> Maybe (NonEmpty v) -> NonEmpty v
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (v
v v -> [v] -> NonEmpty v
forall a. a -> [a] -> NonEmpty a
:| []) (v -> NonEmpty v -> NonEmpty v
forall a. a -> NonEmpty a -> NonEmpty a
NE.cons v
v)) k
k Map k (NonEmpty v)
m
ungroupByKey :: forall k v. Map k (NonEmpty v) -> [(k, v)]
ungroupByKey :: Map k (NonEmpty v) -> [(k, v)]
ungroupByKey Map k (NonEmpty v)
m = [(k
k, v
v) | (k
k, NonEmpty v
vs) <- Map k (NonEmpty v) -> [(k, NonEmpty v)]
forall k a. Map k a -> [(k, a)]
Map.toList Map k (NonEmpty v)
m, v
v <- NonEmpty v -> [v]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty v
vs]
runRoundRobin :: s -> (s' -> s) -> [(s -> Maybe s')] -> s
runRoundRobin :: s -> (s' -> s) -> [s -> Maybe s'] -> s
runRoundRobin s
state s' -> s
demote [s -> Maybe s']
processors =
Identity s -> s
forall a. Identity a -> a
runIdentity (Identity s -> s) -> Identity s -> s
forall a b. (a -> b) -> a -> b
$ s -> (s' -> s) -> [s -> Identity (Maybe s')] -> Identity s
forall (m :: * -> *) s s'.
Monad m =>
s -> (s' -> s) -> [s -> m (Maybe s')] -> m s
runRoundRobinM s
state s' -> s
demote ([s -> Identity (Maybe s')] -> Identity s)
-> [s -> Identity (Maybe s')] -> Identity s
forall a b. (a -> b) -> a -> b
$ (Maybe s' -> Identity (Maybe s'))
-> (s -> Maybe s') -> s -> Identity (Maybe s')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe s' -> Identity (Maybe s')
forall a. a -> Identity a
Identity ((s -> Maybe s') -> s -> Identity (Maybe s'))
-> [s -> Maybe s'] -> [s -> Identity (Maybe s')]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [s -> Maybe s']
processors
runRoundRobinM :: Monad m => s -> (s' -> s) -> [(s -> m (Maybe s'))] -> m s
runRoundRobinM :: s -> (s' -> s) -> [s -> m (Maybe s')] -> m s
runRoundRobinM s
state s' -> s
demote [s -> m (Maybe s')]
processors = s -> [s -> m (Maybe s')] -> [s -> m (Maybe s')] -> m s
go s
state [s -> m (Maybe s')]
processors []
where
go :: s -> [s -> m (Maybe s')] -> [s -> m (Maybe s')] -> m s
go !s
s [] [] = s -> m s
forall (f :: * -> *) a. Applicative f => a -> f a
pure s
s
go !s
s [] ![s -> m (Maybe s')]
qs = s -> [s -> m (Maybe s')] -> [s -> m (Maybe s')] -> m s
go s
s ([s -> m (Maybe s')] -> [s -> m (Maybe s')]
forall a. [a] -> [a]
L.reverse [s -> m (Maybe s')]
qs) []
go !s
s (s -> m (Maybe s')
p : [s -> m (Maybe s')]
ps) ![s -> m (Maybe s')]
qs = s -> m (Maybe s')
p s
s m (Maybe s') -> (Maybe s' -> m s) -> m s
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
\case
Maybe s'
Nothing -> s -> [s -> m (Maybe s')] -> [s -> m (Maybe s')] -> m s
go s
s [s -> m (Maybe s')]
ps [s -> m (Maybe s')]
qs
Just s'
s' -> s -> [s -> m (Maybe s')] -> [s -> m (Maybe s')] -> m s
go (s' -> s
demote s'
s') [s -> m (Maybe s')]
ps (s -> m (Maybe s')
p (s -> m (Maybe s')) -> [s -> m (Maybe s')] -> [s -> m (Maybe s')]
forall a. a -> [a] -> [a]
: [s -> m (Maybe s')]
qs)
selectedAssetQuantity :: IsUTxOSelection s u => AssetId -> s u -> Natural
selectedAssetQuantity :: AssetId -> s u -> Natural
selectedAssetQuantity AssetId
asset
= TokenQuantity -> Natural
unTokenQuantity
(TokenQuantity -> Natural)
-> (s u -> TokenQuantity) -> s u -> Natural
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TokenBundle -> AssetId -> TokenQuantity)
-> AssetId -> TokenBundle -> TokenQuantity
forall a b c. (a -> b -> c) -> b -> a -> c
flip TokenBundle -> AssetId -> TokenQuantity
TokenBundle.getQuantity AssetId
asset
(TokenBundle -> TokenQuantity)
-> (s u -> TokenBundle) -> s u -> TokenQuantity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s u -> TokenBundle
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> TokenBundle
UTxOSelection.selectedBalance
selectedCoinQuantity :: IsUTxOSelection s u => s u -> Natural
selectedCoinQuantity :: s u -> Natural
selectedCoinQuantity
= Natural -> Natural
forall a b.
(Integral a, Integral b, IsIntSubType a b ~ 'True) =>
a -> b
intCast
(Natural -> Natural) -> (s u -> Natural) -> s u -> Natural
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coin -> Natural
unCoin
(Coin -> Natural) -> (s u -> Coin) -> s u -> Natural
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TokenBundle -> Coin
TokenBundle.getCoin
(TokenBundle -> Coin) -> (s u -> TokenBundle) -> s u -> Coin
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s u -> TokenBundle
forall (s :: * -> *) u. IsUTxOSelection s u => s u -> TokenBundle
UTxOSelection.selectedBalance
instance Ord (AssetCount TokenMap) where
compare :: AssetCount TokenMap -> AssetCount TokenMap -> Ordering
compare = (AssetCount TokenMap -> (Int, Lexicographic TokenMap))
-> AssetCount TokenMap -> AssetCount TokenMap -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing AssetCount TokenMap -> (Int, Lexicographic TokenMap)
projection
where
projection :: AssetCount TokenMap -> (Int, Lexicographic TokenMap)
projection (AssetCount TokenMap
m) = (TokenMap -> Int
TokenMap.size TokenMap
m, TokenMap -> Lexicographic TokenMap
forall a. a -> Lexicographic a
Lexicographic TokenMap
m)
newtype AssetCount a = AssetCount
{ AssetCount a -> a
unAssetCount :: a }
deriving (AssetCount a -> AssetCount a -> Bool
(AssetCount a -> AssetCount a -> Bool)
-> (AssetCount a -> AssetCount a -> Bool) -> Eq (AssetCount a)
forall a. Eq a => AssetCount a -> AssetCount a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AssetCount a -> AssetCount a -> Bool
$c/= :: forall a. Eq a => AssetCount a -> AssetCount a -> Bool
== :: AssetCount a -> AssetCount a -> Bool
$c== :: forall a. Eq a => AssetCount a -> AssetCount a -> Bool
Eq, Int -> AssetCount a -> ShowS
[AssetCount a] -> ShowS
AssetCount a -> String
(Int -> AssetCount a -> ShowS)
-> (AssetCount a -> String)
-> ([AssetCount a] -> ShowS)
-> Show (AssetCount a)
forall a. Show a => Int -> AssetCount a -> ShowS
forall a. Show a => [AssetCount a] -> ShowS
forall a. Show a => AssetCount a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AssetCount a] -> ShowS
$cshowList :: forall a. Show a => [AssetCount a] -> ShowS
show :: AssetCount a -> String
$cshow :: forall a. Show a => AssetCount a -> String
showsPrec :: Int -> AssetCount a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> AssetCount a -> ShowS
Show)
distance :: Natural -> Natural -> Natural
distance :: Natural -> Natural -> Natural
distance Natural
a Natural
b
| Natural
a Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
> Natural
b = Natural
a Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
- Natural
b
| Natural
a Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
< Natural
b = Natural
b Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
- Natural
a
| Bool
otherwise = Natural
0
mapMaybe :: (a -> Maybe b) -> NonEmpty a -> [b]
mapMaybe :: (a -> Maybe b) -> NonEmpty a -> [b]
mapMaybe a -> Maybe b
predicate (a
x :| [a]
xs) = [a] -> [b]
go (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs)
where
go :: [a] -> [b]
go [] = []
go (a
a:[a]
as) =
case a -> Maybe b
predicate a
a of
Just b
b -> b
b b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [a] -> [b]
go [a]
as
Maybe b
Nothing -> [a] -> [b]
go [a]
as