From 1b7df63b87bbc33495b69ce24f7eff57e8ba30db Mon Sep 17 00:00:00 2001 From: Jonathan Knowles Date: Fri, 28 Jan 2022 09:15:51 +0000 Subject: [PATCH 1/2] Provide a wallet-specific interface for coin selection. This commit provides the module `Cardano.Wallet.CoinSelection`, which provides a wallet-specific interface for coin selection. Wallet features requiring coin selection functionality should import from this module. --- lib/core/cardano-wallet-core.cabal | 1 + lib/core/src/Cardano/Wallet.hs | 43 +++++----- lib/core/src/Cardano/Wallet/Api/Server.hs | 46 +++++------ lib/core/src/Cardano/Wallet/CoinSelection.hs | 82 +++++++++++++++++++ .../Cardano/Wallet/Primitive/CoinSelection.hs | 44 +++++----- .../Wallet/Primitive/CoinSelection/Balance.hs | 12 +-- .../Primitive/CoinSelection/Collateral.hs | 16 ++-- lib/core/src/Cardano/Wallet/Transaction.hs | 10 ++- .../Primitive/CoinSelection/BalanceSpec.hs | 6 +- .../Primitive/CoinSelection/CollateralSpec.hs | 8 +- .../Wallet/Primitive/CoinSelectionSpec.hs | 29 +++---- lib/core/test/unit/Cardano/WalletSpec.hs | 14 ++-- lib/shelley/bench/restore-bench.hs | 4 +- .../src/Cardano/Wallet/Shelley/Transaction.hs | 10 ++- .../Cardano/Wallet/Shelley/TransactionSpec.hs | 37 +++++---- .../stack-nix/cardano-wallet-core.nix | 1 + 16 files changed, 232 insertions(+), 131 deletions(-) create mode 100644 lib/core/src/Cardano/Wallet/CoinSelection.hs diff --git a/lib/core/cardano-wallet-core.cabal b/lib/core/cardano-wallet-core.cabal index 11c0c207368..0fa1896e7d2 100644 --- a/lib/core/cardano-wallet-core.cabal +++ b/lib/core/cardano-wallet-core.cabal @@ -176,6 +176,7 @@ library Cardano.Wallet.Api.Server Cardano.Wallet.Api.Server.Tls Cardano.Wallet.Api.Types + Cardano.Wallet.CoinSelection Cardano.Wallet.Compat Cardano.Wallet.DB Cardano.Wallet.DB.Checkpoints diff --git a/lib/core/src/Cardano/Wallet.hs b/lib/core/src/Cardano/Wallet.hs index 06e80ee010a..717ed7136e1 100644 --- a/lib/core/src/Cardano/Wallet.hs +++ b/lib/core/src/Cardano/Wallet.hs @@ -218,6 +218,25 @@ import Cardano.Crypto.Wallet ( toXPub ) import Cardano.Slotting.Slot ( SlotNo (..) ) +import Cardano.Wallet.CoinSelection + ( Selection + , SelectionBalanceError (..) + , SelectionCollateralRequirement (..) + , SelectionConstraints (..) + , SelectionError (..) + , SelectionOf (..) + , SelectionOutputError (..) + , SelectionParams (..) + , SelectionReportDetailed + , SelectionReportSummarized + , SelectionSkeleton (..) + , UnableToConstructChangeError (..) + , emptySkeleton + , makeSelectionReportDetailed + , makeSelectionReportSummarized + , performSelection + , selectionDelta + ) import Cardano.Wallet.DB ( DBLayer (..) , ErrNoSuchTransaction (..) @@ -296,23 +315,6 @@ import Cardano.Wallet.Primitive.AddressDiscovery.Shared , SharedState (..) , addCosignerAccXPub ) -import Cardano.Wallet.Primitive.CoinSelection - ( Selection - , SelectionCollateralRequirement (..) - , SelectionConstraints (..) - , SelectionError (..) - , SelectionOf (..) - , SelectionOutputInvalidError (..) - , SelectionParams (..) - , SelectionReportDetailed - , SelectionReportSummarized - , makeSelectionReportDetailed - , makeSelectionReportSummarized - , performSelection - , selectionDelta - ) -import Cardano.Wallet.Primitive.CoinSelection.Balance - ( SelectionSkeleton (..), emptySkeleton ) import Cardano.Wallet.Primitive.Collateral ( asCollateral ) import Cardano.Wallet.Primitive.Migration @@ -550,7 +552,6 @@ import qualified Cardano.Crypto.Wallet as CC import qualified Cardano.Wallet.Primitive.AddressDiscovery.Random as Rnd import qualified Cardano.Wallet.Primitive.AddressDiscovery.Sequential as Seq import qualified Cardano.Wallet.Primitive.AddressDiscovery.Shared as Shared -import qualified Cardano.Wallet.Primitive.CoinSelection.Balance as Balance import qualified Cardano.Wallet.Primitive.Migration as Migration import qualified Cardano.Wallet.Primitive.Types as W import qualified Cardano.Wallet.Primitive.Types.Coin as Coin @@ -2690,9 +2691,9 @@ estimateFee handleCannotCover :: ErrSelectAssets -> ExceptT ErrSelectAssets m Coin handleCannotCover = \case e@(ErrSelectAssetsSelectionError se) -> case se of - SelectionBalanceError (Balance.UnableToConstructChange ce) -> + SelectionBalanceErrorOf (UnableToConstructChange ce) -> case ce of - Balance.UnableToConstructChangeError {requiredCost} -> + UnableToConstructChangeError {requiredCost} -> pure requiredCost _ -> throwE e @@ -3161,7 +3162,7 @@ data ErrCreateMigrationPlan deriving (Generic, Eq, Show) data ErrSelectAssets - = ErrSelectAssetsPrepareOutputsError SelectionOutputInvalidError + = ErrSelectAssetsPrepareOutputsError SelectionOutputError | ErrSelectAssetsNoSuchWallet ErrNoSuchWallet | ErrSelectAssetsAlreadyWithdrawing Tx | ErrSelectAssetsSelectionError SelectionError diff --git a/lib/core/src/Cardano/Wallet/Api/Server.hs b/lib/core/src/Cardano/Wallet/Api/Server.hs index d50cd759c29..7162a319acd 100644 --- a/lib/core/src/Cardano/Wallet/Api/Server.hs +++ b/lib/core/src/Cardano/Wallet/Api/Server.hs @@ -306,6 +306,18 @@ import Cardano.Wallet.Api.Types , toApiNetworkParameters , toApiUtxoStatistics ) +import Cardano.Wallet.CoinSelection + ( SelectionBalanceError (..) + , SelectionCollateralError + , SelectionError (..) + , SelectionOf (..) + , SelectionOutputError (..) + , SelectionOutputSizeExceedsLimitError (..) + , SelectionOutputTokenQuantityExceedsLimitError (..) + , balanceMissing + , selectionDelta + , shortfall + ) import Cardano.Wallet.Compat ( (^?) ) import Cardano.Wallet.DB @@ -370,16 +382,6 @@ import Cardano.Wallet.Primitive.AddressDiscovery.Shared , mkSharedStateFromRootXPrv , validateScriptTemplates ) -import Cardano.Wallet.Primitive.CoinSelection - ( SelectionError (..) - , SelectionOf (..) - , SelectionOutputInvalidError (..) - , SelectionOutputSizeExceedsLimitError (..) - , SelectionOutputTokenQuantityExceedsLimitError (..) - , selectionDelta - ) -import Cardano.Wallet.Primitive.CoinSelection.Balance - ( UnableToConstructChangeError (..), balanceMissing ) import Cardano.Wallet.Primitive.Delegation.UTxO ( stakeKeyCoinDistr ) import Cardano.Wallet.Primitive.Migration @@ -607,8 +609,6 @@ import qualified Cardano.Wallet.Network as NW import qualified Cardano.Wallet.Primitive.AddressDerivation.Byron as Byron import qualified Cardano.Wallet.Primitive.AddressDerivation.Icarus as Icarus import qualified Cardano.Wallet.Primitive.AddressDiscovery.Shared as Shared -import qualified Cardano.Wallet.Primitive.CoinSelection.Balance as Balance -import qualified Cardano.Wallet.Primitive.CoinSelection.Collateral as Collateral import qualified Cardano.Wallet.Primitive.Types as W import qualified Cardano.Wallet.Primitive.Types.Coin as Coin import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle @@ -4252,7 +4252,7 @@ instance IsServerError (ErrInvalidDerivationIndex 'Soft level) where , "between ", pretty minIx, " and ", pretty maxIx, " without a suffix." ] -instance IsServerError SelectionOutputInvalidError where +instance IsServerError SelectionOutputError where toServerError = \case SelectionOutputSizeExceedsLimit e -> toServerError e @@ -4317,22 +4317,22 @@ instance IsServerError ErrSelectAssets where , "transaction; if, for some reason, you really want a new " , "transaction, then cancel the previous one first." ] - ErrSelectAssetsSelectionError (SelectionBalanceError e) -> + ErrSelectAssetsSelectionError (SelectionBalanceErrorOf e) -> toServerError e - ErrSelectAssetsSelectionError (SelectionCollateralError e) -> + ErrSelectAssetsSelectionError (SelectionCollateralErrorOf e) -> toServerError e - ErrSelectAssetsSelectionError (SelectionOutputError e) -> + ErrSelectAssetsSelectionError (SelectionOutputErrorOf e) -> toServerError e -instance IsServerError (Balance.SelectionError) where +instance IsServerError (SelectionBalanceError) where toServerError = \case - Balance.BalanceInsufficient e -> + BalanceInsufficient e -> apiError err403 NotEnoughMoney $ mconcat [ "I can't process this payment as there are not " , "enough funds available in the wallet. I am " , "missing: ", pretty . Flat $ balanceMissing e ] - Balance.SelectionLimitReached e -> + SelectionLimitReached e -> apiError err403 TransactionIsTooBig $ mconcat [ "I am not able to finalize the transaction " , "because I need to select additional inputs and " @@ -4340,7 +4340,7 @@ instance IsServerError (Balance.SelectionError) where , "sending a smaller amount. I had already selected " , showT (length $ view #inputsSelected e), " inputs." ] - Balance.InsufficientMinCoinValues xs -> + InsufficientMinCoinValues xs -> apiError err403 UtxoTooSmall $ mconcat [ "Some outputs have ada values that are too small. " , "There's a minimum ada value specified by the " @@ -4350,7 +4350,7 @@ instance IsServerError (Balance.SelectionError) where , "must specify enough ada. Here are the problematic " , "outputs:\n" <> pretty (indentF 2 $ blockListF xs) ] - Balance.UnableToConstructChange e -> + UnableToConstructChange e -> apiError err403 CannotCoverFee $ T.unwords [ "I am unable to finalize the transaction, as there" , "is not enough ada available to pay for the fee and" @@ -4360,14 +4360,14 @@ instance IsServerError (Balance.SelectionError) where , "ada to proceed. Try increasing your wallet balance" , "or sending a smaller amount." ] - Balance.EmptyUTxO -> + EmptyUTxO -> apiError err403 NotEnoughMoney $ T.unwords [ "Cannot create a transaction because the wallet" , "has no UTxO entries. At least one UTxO entry is" , "required in order to create a transaction." ] -instance IsServerError (Collateral.SelectionError) where +instance IsServerError SelectionCollateralError where toServerError e = apiError err403 InsufficientCollateral $ T.unwords [ "I'm unable to create this transaction because the balance" diff --git a/lib/core/src/Cardano/Wallet/CoinSelection.hs b/lib/core/src/Cardano/Wallet/CoinSelection.hs new file mode 100644 index 00000000000..48ca63ff542 --- /dev/null +++ b/lib/core/src/Cardano/Wallet/CoinSelection.hs @@ -0,0 +1,82 @@ +-- | +-- Copyright: © 2022 IOHK +-- License: Apache-2.0 +-- +-- This module provides a wallet-specific interface for coin selection. +-- +-- Coin selection handles the following responsibilities: +-- +-- - selecting inputs from the UTxO set to pay for user-specified outputs; +-- - selecting inputs from the UTxO set to pay for collateral; +-- - producing change outputs to return excess value to the wallet; +-- - balancing a selection to pay for the transaction fee. +-- +-- Use the 'performSelection' function to perform a coin selection. +-- +module Cardano.Wallet.CoinSelection + ( + -- * Performing selections + performSelection + , Selection + , SelectionCollateralRequirement (..) + , SelectionConstraints (..) + , SelectionError (..) + , SelectionLimit + , SelectionLimitOf (..) + , SelectionOf (..) + , SelectionParams (..) + + -- * Selection skeletons + , SelectionSkeleton (..) + , emptySkeleton + + -- * Selection errors + , BalanceInsufficientError (..) + , SelectionBalanceError (..) + , SelectionCollateralError + , SelectionOutputError (..) + , SelectionOutputSizeExceedsLimitError (..) + , SelectionOutputTokenQuantityExceedsLimitError (..) + , UnableToConstructChangeError (..) + + -- * Selection reports + , makeSelectionReportDetailed + , makeSelectionReportSummarized + , SelectionReportDetailed + , SelectionReportSummarized + + -- * Selection deltas + , balanceMissing + , selectionDelta + ) + where + +import Cardano.Wallet.Primitive.CoinSelection + ( Selection + , SelectionCollateralRequirement (..) + , SelectionConstraints (..) + , SelectionError (..) + , SelectionOf (..) + , SelectionOutputError (..) + , SelectionOutputSizeExceedsLimitError (..) + , SelectionOutputTokenQuantityExceedsLimitError (..) + , SelectionParams (..) + , SelectionReportDetailed + , SelectionReportSummarized + , makeSelectionReportDetailed + , makeSelectionReportSummarized + , performSelection + , selectionDelta + ) +import Cardano.Wallet.Primitive.CoinSelection.Balance + ( BalanceInsufficientError (..) + , SelectionBalanceError (..) + , SelectionLimit + , SelectionLimitOf (..) + , SelectionSkeleton (..) + , UnableToConstructChangeError (..) + , balanceMissing + , emptySkeleton + ) +import Cardano.Wallet.Primitive.CoinSelection.Collateral + ( SelectionCollateralError ) diff --git a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection.hs b/lib/core/src/Cardano/Wallet/Primitive/CoinSelection.hs index aef947454fa..ddb3cb1a854 100644 --- a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection.hs +++ b/lib/core/src/Cardano/Wallet/Primitive/CoinSelection.hs @@ -36,7 +36,7 @@ module Cardano.Wallet.Primitive.CoinSelection -- * Output preparation , prepareOutputsWith - , SelectionOutputInvalidError (..) + , SelectionOutputError (..) , SelectionOutputSizeExceedsLimitError (..) , SelectionOutputTokenQuantityExceedsLimitError (..) @@ -82,7 +82,13 @@ import Prelude import Algebra.PartialOrd ( PartialOrd (..) ) import Cardano.Wallet.Primitive.CoinSelection.Balance - ( SelectionDelta (..), SelectionLimit, SelectionSkeleton ) + ( SelectionBalanceError (..) + , SelectionDelta (..) + , SelectionLimit + , SelectionSkeleton + ) +import Cardano.Wallet.Primitive.CoinSelection.Collateral + ( SelectionCollateralError ) import Cardano.Wallet.Primitive.Types.Address ( Address (..) ) import Cardano.Wallet.Primitive.Types.Coin @@ -247,12 +253,12 @@ data SelectionParams = SelectionParams -- | Indicates that an error occurred while performing a coin selection. -- data SelectionError - = SelectionBalanceError - Balance.SelectionError - | SelectionCollateralError - Collateral.SelectionError - | SelectionOutputError - SelectionOutputInvalidError + = SelectionBalanceErrorOf + SelectionBalanceError + | SelectionCollateralErrorOf + SelectionCollateralError + | SelectionOutputErrorOf + SelectionOutputError deriving (Eq, Show) -- | Represents a balanced selection. @@ -339,7 +345,7 @@ prepareOutputs :: Applicative m => PerformSelection m SelectionParams prepareOutputs cs ps = - withExceptT SelectionOutputError $ ExceptT $ pure $ + withExceptT SelectionOutputErrorOf $ ExceptT $ pure $ flip (set #outputsToCover) ps <$> prepareOutputsInternal cs (view #outputsToCover ps) @@ -347,7 +353,7 @@ performSelectionBalance :: (HasCallStack, MonadRandom m) => PerformSelection m Balance.SelectionResult performSelectionBalance cs ps = - withExceptT SelectionBalanceError $ ExceptT $ + withExceptT SelectionBalanceErrorOf $ ExceptT $ uncurry Balance.performSelection $ toBalanceConstraintsParams (cs, ps) performSelectionCollateral @@ -356,7 +362,7 @@ performSelectionCollateral -> PerformSelection m Collateral.SelectionResult performSelectionCollateral balanceResult cs ps | selectionCollateralRequired ps = - withExceptT SelectionCollateralError $ ExceptT $ pure $ + withExceptT SelectionCollateralErrorOf $ ExceptT $ pure $ uncurry Collateral.performSelection $ toCollateralConstraintsParams balanceResult (cs, ps) | otherwise = @@ -842,18 +848,18 @@ type VerifySelectionError e = -- verifySelectionError :: VerifySelectionError SelectionError verifySelectionError cs ps = \case - SelectionBalanceError e -> + SelectionBalanceErrorOf e -> verifySelectionBalanceError cs ps e - SelectionCollateralError e -> + SelectionCollateralErrorOf e -> verifySelectionCollateralError cs ps e - SelectionOutputError e -> + SelectionOutputErrorOf e -> verifySelectionOutputError cs ps e -------------------------------------------------------------------------------- -- Selection error verification: balance errors -------------------------------------------------------------------------------- -verifySelectionBalanceError :: VerifySelectionError Balance.SelectionError +verifySelectionBalanceError :: VerifySelectionError SelectionBalanceError verifySelectionBalanceError cs ps = \case Balance.BalanceInsufficient e -> verifyBalanceInsufficientError cs ps e @@ -1103,7 +1109,7 @@ data FailureToVerifySelectionCollateralError = } deriving (Eq, Show) -verifySelectionCollateralError :: VerifySelectionError Collateral.SelectionError +verifySelectionCollateralError :: VerifySelectionError SelectionCollateralError verifySelectionCollateralError cs ps e = verifyAll [ Map.null largestCombinationUnsuitableSubset @@ -1149,7 +1155,7 @@ verifySelectionCollateralError cs ps e = -- Selection error verification: output errors -------------------------------------------------------------------------------- -verifySelectionOutputError :: VerifySelectionError SelectionOutputInvalidError +verifySelectionOutputError :: VerifySelectionError SelectionOutputError verifySelectionOutputError cs ps = \case SelectionOutputSizeExceedsLimit e -> verifySelectionOutputSizeExceedsLimitError cs ps e @@ -1376,7 +1382,7 @@ computeMinimumCollateral params = prepareOutputsInternal :: SelectionConstraints -> [TxOut] - -> Either SelectionOutputInvalidError [TxOut] + -> Either SelectionOutputError [TxOut] prepareOutputsInternal constraints outputsUnprepared | e : _ <- excessivelyLargeBundles = Left $ @@ -1435,7 +1441,7 @@ prepareOutputsWith minCoinValueFor = -- | Indicates a problem when preparing outputs for a coin selection. -- -data SelectionOutputInvalidError +data SelectionOutputError = SelectionOutputSizeExceedsLimit SelectionOutputSizeExceedsLimitError | SelectionOutputTokenQuantityExceedsLimit diff --git a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance.hs b/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance.hs index 157cebf8918..38e3997f5d3 100644 --- a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance.hs +++ b/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance.hs @@ -37,7 +37,7 @@ module Cardano.Wallet.Primitive.CoinSelection.Balance , SelectionSkeleton (..) , SelectionResult , SelectionResultOf (..) - , SelectionError (..) + , SelectionBalanceError (..) , BalanceInsufficientError (..) , InsufficientMinCoinValueError (..) , UnableToConstructChangeError (..) @@ -651,7 +651,7 @@ selectionMaximumCost c = mtimesDefault (2 :: Int) . selectionMinimumCost c -- | Represents the set of errors that may occur while performing a selection. -- -data SelectionError +data SelectionBalanceError = BalanceInsufficient BalanceInsufficientError | SelectionLimitReached @@ -732,7 +732,7 @@ data UnableToConstructChangeError = UnableToConstructChangeError type PerformSelection m outputs = SelectionConstraints -> SelectionParamsOf outputs -> - m (Either SelectionError (SelectionResultOf outputs)) + m (Either SelectionBalanceError (SelectionResultOf outputs)) -- | Performs a coin selection and generates change bundles in one step. -- @@ -871,7 +871,9 @@ performSelectionNonEmpty constraints params , assetsToBurn } = params - selectionLimitReachedError :: [(TxIn, TxOut)] -> m (Either SelectionError a) + selectionLimitReachedError + :: [(TxIn, TxOut)] + -> m (Either SelectionBalanceError a) selectionLimitReachedError inputsSelected = pure $ Left $ SelectionLimitReached $ SelectionLimitReachedError { inputsSelected @@ -980,7 +982,7 @@ performSelectionNonEmpty constraints params -- makeChangeRepeatedly :: UTxOSelectionNonEmpty - -> m (Either SelectionError (SelectionResultOf (NonEmpty TxOut))) + -> m (Either SelectionBalanceError (SelectionResultOf (NonEmpty TxOut))) makeChangeRepeatedly s = case mChangeGenerated of Right change | length change >= length outputsToCover -> diff --git a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Collateral.hs b/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Collateral.hs index 23409ce8114..2071540d467 100644 --- a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Collateral.hs +++ b/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Collateral.hs @@ -31,8 +31,8 @@ module Cardano.Wallet.Primitive.CoinSelection.Collateral , SelectionResult , SelectionResultOf (..) , selectionResultEmpty - , SelectionError - , SelectionErrorOf (..) + , SelectionCollateralError + , SelectionCollateralErrorOf (..) , SearchSpaceLimit (..) , searchSpaceLimitDefault @@ -102,7 +102,7 @@ import qualified Numeric.SpecFunctions as MathFast type PerformSelectionOf inputId = SelectionConstraints -> SelectionParamsOf inputId -> - Either (SelectionErrorOf inputId) (SelectionResultOf inputId) + Either (SelectionCollateralErrorOf inputId) (SelectionResultOf inputId) -- | The default type for 'PerformSelectionOf'. -- @@ -188,7 +188,7 @@ selectionResultEmpty = SelectionResult -- | Represents an unsuccessful attempt to select collateral. -- -data SelectionErrorOf inputId = SelectionError +data SelectionCollateralErrorOf inputId = SelectionCollateralError { largestCombinationAvailable :: Map inputId Coin -- ^ The largest combination of coins available. , minimumSelectionAmount :: Coin @@ -196,9 +196,9 @@ data SelectionErrorOf inputId = SelectionError } deriving (Eq, Generic, Show) --- | The default type for `SelectionErrorOf`. +-- | The default type for `SelectionCollateralErrorOf`. -- -type SelectionError = SelectionErrorOf TxIn +type SelectionCollateralError = SelectionCollateralErrorOf TxIn -- | Selects coins for collateral. -- @@ -263,7 +263,7 @@ selectCollateralSmallest constraints params = Just coinsSelected -> Right SelectionResult {coinsSelected} Nothing -> - Left SelectionError + Left SelectionCollateralError { largestCombinationAvailable = mempty , minimumSelectionAmount } @@ -332,7 +332,7 @@ selectCollateralLargest constraints params = Just coinsSelected -> Right SelectionResult {coinsSelected} Nothing -> - Left SelectionError + Left SelectionCollateralError { largestCombinationAvailable , minimumSelectionAmount } diff --git a/lib/core/src/Cardano/Wallet/Transaction.hs b/lib/core/src/Cardano/Wallet/Transaction.hs index 4930a93512a..88e3b499a7c 100644 --- a/lib/core/src/Cardano/Wallet/Transaction.hs +++ b/lib/core/src/Cardano/Wallet/Transaction.hs @@ -43,12 +43,14 @@ import Cardano.Address.Derivation ( XPrv, XPub ) import Cardano.Api ( AnyCardanoEra ) +import Cardano.Wallet.CoinSelection + ( SelectionCollateralRequirement (..) + , SelectionLimit + , SelectionOf (..) + , SelectionSkeleton + ) import Cardano.Wallet.Primitive.AddressDerivation ( Depth (..), DerivationIndex, Passphrase ) -import Cardano.Wallet.Primitive.CoinSelection - ( SelectionCollateralRequirement (..), SelectionOf (..) ) -import Cardano.Wallet.Primitive.CoinSelection.Balance - ( SelectionLimit, SelectionSkeleton ) import Cardano.Wallet.Primitive.Slotting ( PastHorizonException, TimeInterpreter ) import Cardano.Wallet.Primitive.Types diff --git a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/BalanceSpec.hs b/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/BalanceSpec.hs index 99538a25f8f..1367b1fd37a 100644 --- a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/BalanceSpec.hs +++ b/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/BalanceSpec.hs @@ -46,8 +46,8 @@ import Cardano.Wallet.Primitive.CoinSelection.Balance , MakeChangeCriteria (..) , PerformSelection , RunSelectionParams (..) + , SelectionBalanceError (..) , SelectionConstraints (..) - , SelectionError (..) , SelectionLens (..) , SelectionLimit , SelectionLimitOf (..) @@ -573,7 +573,7 @@ prop_AssetCount_TokenMap_placesEmptyMapsFirst maps = -- -- We define this type alias to shorten type signatures. -- -type PerformSelectionResult = Either SelectionError SelectionResult +type PerformSelectionResult = Either SelectionBalanceError SelectionResult genSelectionParams :: Gen (TxIn -> Bool) -> Gen UTxOIndex -> Gen SelectionParams genSelectionParams genPreselectedInputs genUTxOIndex' = do @@ -928,7 +928,7 @@ prop_performSelection mockConstraints params coverage = (view #inputsSelected result <&> fst) (view #utxoAvailable params) - onFailure :: SelectionError -> Property + onFailure :: SelectionBalanceError -> Property onFailure = \case BalanceInsufficient e -> onBalanceInsufficient e diff --git a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/CollateralSpec.hs b/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/CollateralSpec.hs index c71dfac2cda..70977ef4d5d 100644 --- a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/CollateralSpec.hs +++ b/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/CollateralSpec.hs @@ -28,8 +28,8 @@ import Cardano.Wallet.Primitive.CoinSelection.Collateral ( PerformSelectionOf , SearchSpaceLimit (..) , SearchSpaceRequirement (..) + , SelectionCollateralErrorOf (..) , SelectionConstraints (..) - , SelectionErrorOf (..) , SelectionParamsOf (..) , SelectionResultOf (..) , firstRight @@ -226,7 +226,7 @@ prop_performSelection_general_withResult :: (Ord inputId, Show inputId) => SelectionConstraints -> SelectionParamsOf inputId - -> Either (SelectionErrorOf inputId) (SelectionResultOf inputId) + -> Either (SelectionCollateralErrorOf inputId) (SelectionResultOf inputId) -> Property prop_performSelection_general_withResult constraints params eitherErrorResult = cover 20.0 (isLeft eitherErrorResult) "Failure" $ @@ -241,7 +241,7 @@ prop_performSelection_onFailure :: (Ord inputId, Show inputId) => SelectionConstraints -> SelectionParamsOf inputId - -> SelectionErrorOf inputId + -> SelectionCollateralErrorOf inputId -> Property prop_performSelection_onFailure constraints params err = counterexample ("Error: " <> show (Pretty err)) $ @@ -670,7 +670,7 @@ unitTests_selectCollateralLargest_insufficient = unitTests , minimumSelectionAmount = Coin minimumSelectionAmount } ) - , result = Left SelectionError + , result = Left SelectionCollateralError { largestCombinationAvailable = Coin <$> largestCombinationAvailable , minimumSelectionAmount = diff --git a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelectionSpec.hs b/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelectionSpec.hs index 1d9258727c3..c49ddc2a618 100644 --- a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelectionSpec.hs +++ b/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelectionSpec.hs @@ -21,7 +21,7 @@ import Cardano.Wallet.Primitive.CoinSelection , SelectionCollateralRequirement (..) , SelectionConstraints (..) , SelectionError (..) - , SelectionOutputInvalidError (..) + , SelectionOutputError (..) , SelectionParams (..) , VerificationResult (..) , computeMinimumCollateral @@ -54,6 +54,8 @@ import Cardano.Wallet.Primitive.CoinSelection.BalanceSpec , unMockComputeMinimumCost , unMockComputeSelectionLimit ) +import Cardano.Wallet.Primitive.CoinSelection.Collateral + ( SelectionCollateralErrorOf (..) ) import Cardano.Wallet.Primitive.Types.Address.Gen ( genAddress ) import Cardano.Wallet.Primitive.Types.Coin @@ -136,7 +138,6 @@ import Test.QuickCheck.Monadic ( monadicIO, run ) import qualified Cardano.Wallet.Primitive.CoinSelection.Balance as Balance -import qualified Cardano.Wallet.Primitive.CoinSelection.Collateral as Collateral import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle import qualified Cardano.Wallet.Primitive.Types.TokenMap as TokenMap import qualified Cardano.Wallet.Primitive.Types.UTxOSelection as UTxOSelection @@ -249,28 +250,28 @@ prop_performSelection_coverage params r innerProperty = where isSelection = isRight isSelectionBalanceError_BalanceInsufficient = \case - Left (SelectionBalanceError Balance.BalanceInsufficient {}) + Left (SelectionBalanceErrorOf Balance.BalanceInsufficient {}) -> True; _ -> False isSelectionBalanceError_SelectionLimitReached = \case - Left (SelectionBalanceError Balance.SelectionLimitReached {}) + Left (SelectionBalanceErrorOf Balance.SelectionLimitReached {}) -> True; _ -> False isSelectionBalanceError_InsufficientMinCoinValues = \case - Left (SelectionBalanceError Balance.InsufficientMinCoinValues {}) + Left (SelectionBalanceErrorOf Balance.InsufficientMinCoinValues {}) -> True; _ -> False isSelectionBalanceError_UnableToConstructChange = \case - Left (SelectionBalanceError Balance.UnableToConstructChange {}) + Left (SelectionBalanceErrorOf Balance.UnableToConstructChange {}) -> True; _ -> False isSelectionBalanceError_EmptyUTxO = \case - Left (SelectionBalanceError Balance.EmptyUTxO {}) + Left (SelectionBalanceErrorOf Balance.EmptyUTxO {}) -> True; _ -> False isSelectionCollateralError = \case - Left (SelectionCollateralError _) + Left (SelectionCollateralErrorOf _) -> True; _ -> False isSelectionOutputError_SelectionOutputSizeExceedsLimit = \case - Left (SelectionOutputError SelectionOutputSizeExceedsLimit {}) + Left (SelectionOutputErrorOf SelectionOutputSizeExceedsLimit {}) -> True; _ -> False isSelectionOutputError_SelectionOutputTokenQuantityExceedsLimit = \case - Left (SelectionOutputError SelectionOutputTokenQuantityExceedsLimit {}) + Left (SelectionOutputErrorOf SelectionOutputTokenQuantityExceedsLimit {}) -> True; _ -> False -- Provides an exhaustiveness check for all possible constructors of @@ -282,15 +283,15 @@ prop_performSelection_coverage params r innerProperty = -- _checkExhaustivenessForSelectionError :: () _checkExhaustivenessForSelectionError = case undefined of - SelectionBalanceError e -> case e of + SelectionBalanceErrorOf e -> case e of Balance.BalanceInsufficient {} -> () Balance.SelectionLimitReached {} -> () Balance.InsufficientMinCoinValues {} -> () Balance.UnableToConstructChange {} -> () Balance.EmptyUTxO {} -> () - SelectionCollateralError e -> case e of - Collateral.SelectionError {} -> () - SelectionOutputError e -> case e of + SelectionCollateralErrorOf e -> case e of + SelectionCollateralError {} -> () + SelectionOutputErrorOf e -> case e of SelectionOutputSizeExceedsLimit {} -> () SelectionOutputTokenQuantityExceedsLimit {} -> () diff --git a/lib/core/test/unit/Cardano/WalletSpec.hs b/lib/core/test/unit/Cardano/WalletSpec.hs index 6cc032a7189..8da026b863c 100644 --- a/lib/core/test/unit/Cardano/WalletSpec.hs +++ b/lib/core/test/unit/Cardano/WalletSpec.hs @@ -37,6 +37,11 @@ import Cardano.Wallet , runLocalTxSubmissionPool , throttle ) +import Cardano.Wallet.CoinSelection + ( BalanceInsufficientError (..) + , SelectionBalanceError (..) + , SelectionError (..) + ) import Cardano.Wallet.DB ( DBLayer (..), ErrNoSuchWallet (..), putTxHistory ) import Cardano.Wallet.DummyTarget.Primitive.Types @@ -76,8 +81,6 @@ import Cardano.Wallet.Primitive.AddressDiscovery , IsOwned (..) , KnownAddresses (..) ) -import Cardano.Wallet.Primitive.CoinSelection - ( SelectionError (..) ) import Cardano.Wallet.Primitive.Migration.SelectionSpec ( MockTxConstraints (..), genTokenBundleMixed, unMockTxConstraints ) import Cardano.Wallet.Primitive.SyncProgress @@ -266,7 +269,6 @@ import qualified Cardano.Wallet as W import qualified Cardano.Wallet.DB.MVar as MVar import qualified Cardano.Wallet.DB.Sqlite as Sqlite import qualified Cardano.Wallet.DB.Sqlite.AddressBook as Sqlite -import qualified Cardano.Wallet.Primitive.CoinSelection.Balance as Balance import qualified Cardano.Wallet.Primitive.Migration as Migration import qualified Cardano.Wallet.Primitive.Types.Coin as Coin import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle @@ -661,9 +663,9 @@ prop_estimateFee (NonEmpty coins) = genericError :: W.ErrSelectAssets genericError = W.ErrSelectAssetsSelectionError - $ SelectionBalanceError - $ Balance.BalanceInsufficient - $ Balance.BalanceInsufficientError TokenBundle.empty TokenBundle.empty + $ SelectionBalanceErrorOf + $ BalanceInsufficient + $ BalanceInsufficientError TokenBundle.empty TokenBundle.empty runSelection :: ExceptT W.ErrSelectAssets (State Int) Coin diff --git a/lib/shelley/bench/restore-bench.hs b/lib/shelley/bench/restore-bench.hs index c92714073b2..741a16f9227 100644 --- a/lib/shelley/bench/restore-bench.hs +++ b/lib/shelley/bench/restore-bench.hs @@ -68,6 +68,8 @@ import Cardano.Wallet.BenchShared , initBenchmarkLogging , runBenchmarks ) +import Cardano.Wallet.CoinSelection + ( selectionDelta ) import Cardano.Wallet.DB ( DBLayer ) import Cardano.Wallet.DB.Sqlite @@ -102,8 +104,6 @@ import Cardano.Wallet.Primitive.AddressDiscovery.Sequential , mkSeqAnyState , purposeCIP1852 ) -import Cardano.Wallet.Primitive.CoinSelection - ( selectionDelta ) import Cardano.Wallet.Primitive.Model ( Wallet, currentTip, getState, totalUTxO ) import Cardano.Wallet.Primitive.Slotting diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Transaction.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Transaction.hs index 5f130ee468e..85e0f85bc69 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Transaction.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Transaction.hs @@ -83,6 +83,12 @@ import Cardano.Ledger.Shelley.API ( StrictMaybe (..) ) import Cardano.Slotting.EpochInfo.API ( hoistEpochInfo ) +import Cardano.Wallet.CoinSelection + ( SelectionLimitOf (..) + , SelectionOf (..) + , SelectionSkeleton (..) + , selectionDelta + ) import Cardano.Wallet.Primitive.AddressDerivation ( Depth (..), Passphrase (..), RewardAccount (..), WalletKey (..) ) import Cardano.Wallet.Primitive.AddressDerivation.Byron @@ -91,10 +97,6 @@ import Cardano.Wallet.Primitive.AddressDerivation.Icarus ( IcarusKey ) import Cardano.Wallet.Primitive.AddressDerivation.Shelley ( ShelleyKey, toRewardAccountRaw ) -import Cardano.Wallet.Primitive.CoinSelection - ( SelectionOf (..), selectionDelta ) -import Cardano.Wallet.Primitive.CoinSelection.Balance - ( SelectionLimitOf (..), SelectionSkeleton (..) ) import Cardano.Wallet.Primitive.Slotting ( PastHorizonException, TimeInterpreter, getSystemStart, toEpochInfo ) import Cardano.Wallet.Primitive.Types diff --git a/lib/shelley/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs b/lib/shelley/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs index f81f002fe17..9eb453dea42 100644 --- a/lib/shelley/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs +++ b/lib/shelley/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs @@ -81,6 +81,15 @@ import Cardano.Wallet ) import Cardano.Wallet.Byron.Compatibility ( maryTokenBundleMaxSize ) +import Cardano.Wallet.CoinSelection + ( SelectionBalanceError (..) + , SelectionError (..) + , SelectionOf (..) + , UnableToConstructChangeError (..) + , balanceMissing + , emptySkeleton + , selectionDelta + ) import Cardano.Wallet.Gen ( genMnemonic, genScript ) import Cardano.Wallet.Primitive.AddressDerivation @@ -108,13 +117,6 @@ import Cardano.Wallet.Primitive.AddressDerivation.Shelley ( ShelleyKey, generateKeyFromSeed ) import Cardano.Wallet.Primitive.AddressDiscovery.Sequential ( SeqState, defaultAddressPoolGap, mkSeqStateFromRootXPrv, purposeCIP1852 ) -import Cardano.Wallet.Primitive.CoinSelection - ( SelectionError (..), SelectionOf (..), selectionDelta ) -import Cardano.Wallet.Primitive.CoinSelection.Balance - ( SelectionError (EmptyUTxO, SelectionLimitReached) - , UnableToConstructChangeError (..) - , emptySkeleton - ) import Cardano.Wallet.Primitive.Model ( Wallet (..), unsafeInitWallet ) import Cardano.Wallet.Primitive.Slotting @@ -350,7 +352,6 @@ import qualified Cardano.Ledger.Core as Ledger import qualified Cardano.Ledger.Crypto as Crypto import qualified Cardano.Ledger.Shelley.API as SL import qualified Cardano.Wallet.Primitive.AddressDerivation.Shelley as Shelley -import qualified Cardano.Wallet.Primitive.CoinSelection.Balance as Balance 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 @@ -1211,9 +1212,9 @@ feeEstimationRegressionSpec = describe "Regression tests" $ do let requiredCost = 166029 let runSelection = except $ Left $ ErrSelectAssetsSelectionError - $ SelectionBalanceError - $ Balance.UnableToConstructChange - $ Balance.UnableToConstructChangeError + $ SelectionBalanceErrorOf + $ UnableToConstructChange + $ UnableToConstructChangeError { requiredCost = Coin.fromWord64 requiredCost , shortfall = Coin 100000 } @@ -2311,8 +2312,8 @@ prop_balanceTransactionBalanced (Wallet' utxo wal pending) (ShowBuildable partia Left (ErrBalanceTxSelectAssets (ErrSelectAssetsSelectionError - (SelectionBalanceError (Balance.BalanceInsufficient err)))) -> do - let missing = Balance.balanceMissing err + (SelectionBalanceErrorOf (BalanceInsufficient err)))) -> do + let missing = balanceMissing err case (view #coin missing == Coin 0, view #tokens missing == mempty) of (False, False) -> label "missing coin and tokens" $ property True (False, True) -> label "missing coin" $ property True @@ -2323,8 +2324,8 @@ prop_balanceTransactionBalanced (Wallet' utxo wal pending) (ShowBuildable partia Left (ErrBalanceTxSelectAssets (ErrSelectAssetsSelectionError - (SelectionBalanceError - (Balance.InsufficientMinCoinValues _)))) -> + (SelectionBalanceErrorOf + (InsufficientMinCoinValues _)))) -> label "outputs below minCoinValue" $ property True Left (ErrBalanceTxNotYetSupported Deposits) -> label ("not yet supported: deposits") True @@ -2339,18 +2340,18 @@ prop_balanceTransactionBalanced (Wallet' utxo wal pending) (ShowBuildable partia Left (ErrBalanceTxSelectAssets (ErrSelectAssetsSelectionError - (SelectionBalanceError EmptyUTxO))) -> + (SelectionBalanceErrorOf EmptyUTxO))) -> label "empty UTxO" $ property True Left (ErrBalanceTxSelectAssets (ErrSelectAssetsSelectionError - (SelectionBalanceError + (SelectionBalanceErrorOf (SelectionLimitReached _)))) -> label "selection limit reached" $ property True Left (ErrBalanceTxSelectAssets (ErrSelectAssetsSelectionError - (SelectionBalanceError (Balance.UnableToConstructChange _)))) -> + (SelectionBalanceErrorOf (UnableToConstructChange _)))) -> label "unable to construct change" $ property True Left err -> label "other error" $ counterexample ("balanceTransaction failed: " <> show err) False diff --git a/nix/materialized/stack-nix/cardano-wallet-core.nix b/nix/materialized/stack-nix/cardano-wallet-core.nix index 0e6c034d0c5..a1f92d05a7e 100644 --- a/nix/materialized/stack-nix/cardano-wallet-core.nix +++ b/nix/materialized/stack-nix/cardano-wallet-core.nix @@ -171,6 +171,7 @@ "Cardano/Wallet/Api/Server" "Cardano/Wallet/Api/Server/Tls" "Cardano/Wallet/Api/Types" + "Cardano/Wallet/CoinSelection" "Cardano/Wallet/Compat" "Cardano/Wallet/DB" "Cardano/Wallet/DB/Checkpoints" From 72dd574384454ddead01615d5a614bebce8a4f3a Mon Sep 17 00:00:00 2001 From: Jonathan Knowles Date: Mon, 7 Feb 2022 07:08:13 +0000 Subject: [PATCH 2/2] Mark some coin selection modules as "internal". This commit: 1. Renames `Primitive.CoinSelection` to `CoinSelection.Internal`, making it more obvious that this module is an "internal" module. 2. Adds a disclaimer to the top of the module advising people to import from the "public" module instead. --- lib/core/cardano-wallet-core.cabal | 14 ++++++------- lib/core/src/Cardano/Wallet/CoinSelection.hs | 6 +++--- .../Internal.hs} | 21 +++++++------------ .../Internal}/Balance.hs | 2 +- .../Internal}/Balance/Gen.hs | 4 ++-- .../Internal}/Collateral.hs | 2 +- .../Internal}/BalanceSpec.hs | 6 +++--- .../Internal}/CollateralSpec.hs | 4 ++-- .../InternalSpec.hs} | 14 ++++++------- .../stack-nix/cardano-wallet-core.nix | 14 ++++++------- 10 files changed, 40 insertions(+), 47 deletions(-) rename lib/core/src/Cardano/Wallet/{Primitive/CoinSelection.hs => CoinSelection/Internal.hs} (98%) rename lib/core/src/Cardano/Wallet/{Primitive/CoinSelection => CoinSelection/Internal}/Balance.hs (99%) rename lib/core/src/Cardano/Wallet/{Primitive/CoinSelection => CoinSelection/Internal}/Balance/Gen.hs (95%) rename lib/core/src/Cardano/Wallet/{Primitive/CoinSelection => CoinSelection/Internal}/Collateral.hs (99%) rename lib/core/test/unit/Cardano/Wallet/{Primitive/CoinSelection => CoinSelection/Internal}/BalanceSpec.hs (99%) rename lib/core/test/unit/Cardano/Wallet/{Primitive/CoinSelection => CoinSelection/Internal}/CollateralSpec.hs (99%) rename lib/core/test/unit/Cardano/Wallet/{Primitive/CoinSelectionSpec.hs => CoinSelection/InternalSpec.hs} (98%) diff --git a/lib/core/cardano-wallet-core.cabal b/lib/core/cardano-wallet-core.cabal index 0fa1896e7d2..7794fde4bba 100644 --- a/lib/core/cardano-wallet-core.cabal +++ b/lib/core/cardano-wallet-core.cabal @@ -177,6 +177,9 @@ library Cardano.Wallet.Api.Server.Tls Cardano.Wallet.Api.Types Cardano.Wallet.CoinSelection + Cardano.Wallet.CoinSelection.Internal + Cardano.Wallet.CoinSelection.Internal.Balance + Cardano.Wallet.CoinSelection.Internal.Collateral Cardano.Wallet.Compat Cardano.Wallet.DB Cardano.Wallet.DB.Checkpoints @@ -207,9 +210,6 @@ library Cardano.Wallet.Primitive.AddressDiscovery.Sequential Cardano.Wallet.Primitive.AddressDiscovery.Shared Cardano.Wallet.Primitive.SyncProgress - Cardano.Wallet.Primitive.CoinSelection - Cardano.Wallet.Primitive.CoinSelection.Balance - Cardano.Wallet.Primitive.CoinSelection.Collateral Cardano.Wallet.Primitive.Collateral Cardano.Wallet.Primitive.Delegation.UTxO Cardano.Wallet.Primitive.Migration @@ -260,7 +260,7 @@ library -- The following modules define QC generators and shrinkers that can -- be used by both `cardano-wallet-core` and `cardano-wallet`: -- - Cardano.Wallet.Primitive.CoinSelection.Balance.Gen + Cardano.Wallet.CoinSelection.Internal.Balance.Gen Cardano.Wallet.Primitive.Types.Address.Gen Cardano.Wallet.Primitive.Types.Coin.Gen Cardano.Wallet.Primitive.Types.RewardAccount.Gen @@ -415,6 +415,9 @@ test-suite unit Cardano.Wallet.Api.ServerSpec Cardano.Wallet.Api.TypesSpec Cardano.Wallet.ApiSpec + Cardano.Wallet.CoinSelection.InternalSpec + Cardano.Wallet.CoinSelection.Internal.BalanceSpec + Cardano.Wallet.CoinSelection.Internal.CollateralSpec Cardano.Wallet.DB.Arbitrary Cardano.Wallet.DB.MVarSpec Cardano.Wallet.DB.Properties @@ -433,9 +436,6 @@ test-suite unit Cardano.Wallet.Primitive.AddressDiscovery.SharedSpec Cardano.Wallet.Primitive.Delegation.StateSpec Cardano.Wallet.Primitive.AddressDiscoverySpec - Cardano.Wallet.Primitive.CoinSelectionSpec - Cardano.Wallet.Primitive.CoinSelection.BalanceSpec - Cardano.Wallet.Primitive.CoinSelection.CollateralSpec Cardano.Wallet.Primitive.CollateralSpec Cardano.Wallet.Primitive.MigrationSpec Cardano.Wallet.Primitive.Migration.PlanningSpec diff --git a/lib/core/src/Cardano/Wallet/CoinSelection.hs b/lib/core/src/Cardano/Wallet/CoinSelection.hs index 48ca63ff542..9f1132eca0d 100644 --- a/lib/core/src/Cardano/Wallet/CoinSelection.hs +++ b/lib/core/src/Cardano/Wallet/CoinSelection.hs @@ -51,7 +51,7 @@ module Cardano.Wallet.CoinSelection ) where -import Cardano.Wallet.Primitive.CoinSelection +import Cardano.Wallet.CoinSelection.Internal ( Selection , SelectionCollateralRequirement (..) , SelectionConstraints (..) @@ -68,7 +68,7 @@ import Cardano.Wallet.Primitive.CoinSelection , performSelection , selectionDelta ) -import Cardano.Wallet.Primitive.CoinSelection.Balance +import Cardano.Wallet.CoinSelection.Internal.Balance ( BalanceInsufficientError (..) , SelectionBalanceError (..) , SelectionLimit @@ -78,5 +78,5 @@ import Cardano.Wallet.Primitive.CoinSelection.Balance , balanceMissing , emptySkeleton ) -import Cardano.Wallet.Primitive.CoinSelection.Collateral +import Cardano.Wallet.CoinSelection.Internal.Collateral ( SelectionCollateralError ) diff --git a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection.hs b/lib/core/src/Cardano/Wallet/CoinSelection/Internal.hs similarity index 98% rename from lib/core/src/Cardano/Wallet/Primitive/CoinSelection.hs rename to lib/core/src/Cardano/Wallet/CoinSelection/Internal.hs index ddb3cb1a854..10367fae237 100644 --- a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection.hs +++ b/lib/core/src/Cardano/Wallet/CoinSelection/Internal.hs @@ -13,18 +13,11 @@ -- Copyright: © 2021 IOHK -- License: Apache-2.0 -- --- This module provides a high-level interface for coin selection. +-- This module provides INTERNAL functions and types for coin selection. -- --- It handles the following responsibilities: +-- It is recommended to import from 'Cardano.Wallet.CoinSelection' instead. -- --- - selecting inputs from the UTxO set to pay for user-specified outputs; --- - selecting inputs from the UTxO set to pay for collateral; --- - producing change outputs to return excess value to the wallet; --- - balancing a selection to pay for the transaction fee. --- --- Use the 'performSelection' function to perform a coin selection. --- -module Cardano.Wallet.Primitive.CoinSelection +module Cardano.Wallet.CoinSelection.Internal ( -- * Performing selections performSelection @@ -81,13 +74,13 @@ import Prelude import Algebra.PartialOrd ( PartialOrd (..) ) -import Cardano.Wallet.Primitive.CoinSelection.Balance +import Cardano.Wallet.CoinSelection.Internal.Balance ( SelectionBalanceError (..) , SelectionDelta (..) , SelectionLimit , SelectionSkeleton ) -import Cardano.Wallet.Primitive.CoinSelection.Collateral +import Cardano.Wallet.CoinSelection.Internal.Collateral ( SelectionCollateralError ) import Cardano.Wallet.Primitive.Types.Address ( Address (..) ) @@ -140,8 +133,8 @@ import GHC.Stack import Numeric.Natural ( Natural ) -import qualified Cardano.Wallet.Primitive.CoinSelection.Balance as Balance -import qualified Cardano.Wallet.Primitive.CoinSelection.Collateral as Collateral +import qualified Cardano.Wallet.CoinSelection.Internal.Balance as Balance +import qualified Cardano.Wallet.CoinSelection.Internal.Collateral as Collateral import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle import qualified Cardano.Wallet.Primitive.Types.TokenMap as TokenMap import qualified Cardano.Wallet.Primitive.Types.UTxO as UTxO diff --git a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance.hs b/lib/core/src/Cardano/Wallet/CoinSelection/Internal/Balance.hs similarity index 99% rename from lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance.hs rename to lib/core/src/Cardano/Wallet/CoinSelection/Internal/Balance.hs index 38e3997f5d3..aa3839b8a39 100644 --- a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance.hs +++ b/lib/core/src/Cardano/Wallet/CoinSelection/Internal/Balance.hs @@ -24,7 +24,7 @@ -- See documentation for the 'performSelection' function for more details on -- how to perform a selection. -- -module Cardano.Wallet.Primitive.CoinSelection.Balance +module Cardano.Wallet.CoinSelection.Internal.Balance ( -- * Performing a selection PerformSelection diff --git a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance/Gen.hs b/lib/core/src/Cardano/Wallet/CoinSelection/Internal/Balance/Gen.hs similarity index 95% rename from lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance/Gen.hs rename to lib/core/src/Cardano/Wallet/CoinSelection/Internal/Balance/Gen.hs index d2224b6d2d9..bdc7a900791 100644 --- a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance/Gen.hs +++ b/lib/core/src/Cardano/Wallet/CoinSelection/Internal/Balance/Gen.hs @@ -1,7 +1,7 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeApplications #-} -module Cardano.Wallet.Primitive.CoinSelection.Balance.Gen +module Cardano.Wallet.CoinSelection.Internal.Balance.Gen ( genSelectionLimit , genSelectionSkeleton , shrinkSelectionLimit @@ -11,7 +11,7 @@ module Cardano.Wallet.Primitive.CoinSelection.Balance.Gen import Prelude -import Cardano.Wallet.Primitive.CoinSelection.Balance +import Cardano.Wallet.CoinSelection.Internal.Balance ( SelectionLimit, SelectionLimitOf (..), SelectionSkeleton (..) ) import Cardano.Wallet.Primitive.Types.TokenMap.Gen ( genAssetId, shrinkAssetId ) diff --git a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Collateral.hs b/lib/core/src/Cardano/Wallet/CoinSelection/Internal/Collateral.hs similarity index 99% rename from lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Collateral.hs rename to lib/core/src/Cardano/Wallet/CoinSelection/Internal/Collateral.hs index 2071540d467..c164ca2a485 100644 --- a/lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Collateral.hs +++ b/lib/core/src/Cardano/Wallet/CoinSelection/Internal/Collateral.hs @@ -18,7 +18,7 @@ -- -- See the documentation for 'performSelection' for more details. -- -module Cardano.Wallet.Primitive.CoinSelection.Collateral +module Cardano.Wallet.CoinSelection.Internal.Collateral ( -- * Public API diff --git a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/BalanceSpec.hs b/lib/core/test/unit/Cardano/Wallet/CoinSelection/Internal/BalanceSpec.hs similarity index 99% rename from lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/BalanceSpec.hs rename to lib/core/test/unit/Cardano/Wallet/CoinSelection/Internal/BalanceSpec.hs index 1367b1fd37a..5039d5ee6fc 100644 --- a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/BalanceSpec.hs +++ b/lib/core/test/unit/Cardano/Wallet/CoinSelection/Internal/BalanceSpec.hs @@ -13,7 +13,7 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {- HLINT ignore "Use camelCase" -} -module Cardano.Wallet.Primitive.CoinSelection.BalanceSpec +module Cardano.Wallet.CoinSelection.Internal.BalanceSpec ( spec , MockAssessTokenBundleSize , MockComputeMinimumAdaQuantity @@ -39,7 +39,7 @@ import Algebra.PartialOrd ( PartialOrd (..) ) import Cardano.Numeric.Util ( inAscendingPartialOrder ) -import Cardano.Wallet.Primitive.CoinSelection.Balance +import Cardano.Wallet.CoinSelection.Internal.Balance ( AssetCount (..) , BalanceInsufficientError (..) , InsufficientMinCoinValueError (..) @@ -95,7 +95,7 @@ import Cardano.Wallet.Primitive.CoinSelection.Balance , splitBundlesWithExcessiveTokenQuantities , ungroupByKey ) -import Cardano.Wallet.Primitive.CoinSelection.Balance.Gen +import Cardano.Wallet.CoinSelection.Internal.Balance.Gen ( genSelectionLimit, shrinkSelectionLimit ) import Cardano.Wallet.Primitive.Types.Address ( Address (..) ) diff --git a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/CollateralSpec.hs b/lib/core/test/unit/Cardano/Wallet/CoinSelection/Internal/CollateralSpec.hs similarity index 99% rename from lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/CollateralSpec.hs rename to lib/core/test/unit/Cardano/Wallet/CoinSelection/Internal/CollateralSpec.hs index 70977ef4d5d..37860de963e 100644 --- a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/CollateralSpec.hs +++ b/lib/core/test/unit/Cardano/Wallet/CoinSelection/Internal/CollateralSpec.hs @@ -19,12 +19,12 @@ -- Copyright: © 2021 IOHK -- License: Apache-2.0 -- -module Cardano.Wallet.Primitive.CoinSelection.CollateralSpec where +module Cardano.Wallet.CoinSelection.Internal.CollateralSpec where import Prelude hiding ( sequence ) -import Cardano.Wallet.Primitive.CoinSelection.Collateral +import Cardano.Wallet.CoinSelection.Internal.Collateral ( PerformSelectionOf , SearchSpaceLimit (..) , SearchSpaceRequirement (..) diff --git a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelectionSpec.hs b/lib/core/test/unit/Cardano/Wallet/CoinSelection/InternalSpec.hs similarity index 98% rename from lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelectionSpec.hs rename to lib/core/test/unit/Cardano/Wallet/CoinSelection/InternalSpec.hs index c49ddc2a618..4ac065d1e67 100644 --- a/lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelectionSpec.hs +++ b/lib/core/test/unit/Cardano/Wallet/CoinSelection/InternalSpec.hs @@ -10,12 +10,12 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {- HLINT ignore "Use camelCase" -} -module Cardano.Wallet.Primitive.CoinSelectionSpec +module Cardano.Wallet.CoinSelection.InternalSpec where import Prelude -import Cardano.Wallet.Primitive.CoinSelection +import Cardano.Wallet.CoinSelection.Internal ( ComputeMinimumCollateralParams (..) , Selection , SelectionCollateralRequirement (..) @@ -32,11 +32,11 @@ import Cardano.Wallet.Primitive.CoinSelection , verifySelection , verifySelectionError ) -import Cardano.Wallet.Primitive.CoinSelection.Balance +import Cardano.Wallet.CoinSelection.Internal.Balance ( SelectionLimit, SelectionSkeleton ) -import Cardano.Wallet.Primitive.CoinSelection.Balance.Gen +import Cardano.Wallet.CoinSelection.Internal.Balance.Gen ( genSelectionSkeleton, shrinkSelectionSkeleton ) -import Cardano.Wallet.Primitive.CoinSelection.BalanceSpec +import Cardano.Wallet.CoinSelection.Internal.BalanceSpec ( MockAssessTokenBundleSize , MockComputeMinimumAdaQuantity , MockComputeMinimumCost @@ -54,7 +54,7 @@ import Cardano.Wallet.Primitive.CoinSelection.BalanceSpec , unMockComputeMinimumCost , unMockComputeSelectionLimit ) -import Cardano.Wallet.Primitive.CoinSelection.Collateral +import Cardano.Wallet.CoinSelection.Internal.Collateral ( SelectionCollateralErrorOf (..) ) import Cardano.Wallet.Primitive.Types.Address.Gen ( genAddress ) @@ -137,7 +137,7 @@ import Test.QuickCheck.Extra import Test.QuickCheck.Monadic ( monadicIO, run ) -import qualified Cardano.Wallet.Primitive.CoinSelection.Balance as Balance +import qualified Cardano.Wallet.CoinSelection.Internal.Balance as Balance import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle import qualified Cardano.Wallet.Primitive.Types.TokenMap as TokenMap import qualified Cardano.Wallet.Primitive.Types.UTxOSelection as UTxOSelection diff --git a/nix/materialized/stack-nix/cardano-wallet-core.nix b/nix/materialized/stack-nix/cardano-wallet-core.nix index a1f92d05a7e..64de6a1dbe7 100644 --- a/nix/materialized/stack-nix/cardano-wallet-core.nix +++ b/nix/materialized/stack-nix/cardano-wallet-core.nix @@ -172,6 +172,9 @@ "Cardano/Wallet/Api/Server/Tls" "Cardano/Wallet/Api/Types" "Cardano/Wallet/CoinSelection" + "Cardano/Wallet/CoinSelection/Internal" + "Cardano/Wallet/CoinSelection/Internal/Balance" + "Cardano/Wallet/CoinSelection/Internal/Collateral" "Cardano/Wallet/Compat" "Cardano/Wallet/DB" "Cardano/Wallet/DB/Checkpoints" @@ -202,9 +205,6 @@ "Cardano/Wallet/Primitive/AddressDiscovery/Sequential" "Cardano/Wallet/Primitive/AddressDiscovery/Shared" "Cardano/Wallet/Primitive/SyncProgress" - "Cardano/Wallet/Primitive/CoinSelection" - "Cardano/Wallet/Primitive/CoinSelection/Balance" - "Cardano/Wallet/Primitive/CoinSelection/Collateral" "Cardano/Wallet/Primitive/Collateral" "Cardano/Wallet/Primitive/Delegation/UTxO" "Cardano/Wallet/Primitive/Migration" @@ -247,7 +247,7 @@ "Network/Wai/Middleware/Logging" "Ouroboros/Network/Client/Wallet" "UnliftIO/Compat" - "Cardano/Wallet/Primitive/CoinSelection/Balance/Gen" + "Cardano/Wallet/CoinSelection/Internal/Balance/Gen" "Cardano/Wallet/Primitive/Types/Address/Gen" "Cardano/Wallet/Primitive/Types/Coin/Gen" "Cardano/Wallet/Primitive/Types/RewardAccount/Gen" @@ -383,6 +383,9 @@ "Cardano/Wallet/Api/ServerSpec" "Cardano/Wallet/Api/TypesSpec" "Cardano/Wallet/ApiSpec" + "Cardano/Wallet/CoinSelection/InternalSpec" + "Cardano/Wallet/CoinSelection/Internal/BalanceSpec" + "Cardano/Wallet/CoinSelection/Internal/CollateralSpec" "Cardano/Wallet/DB/Arbitrary" "Cardano/Wallet/DB/MVarSpec" "Cardano/Wallet/DB/Properties" @@ -401,9 +404,6 @@ "Cardano/Wallet/Primitive/AddressDiscovery/SharedSpec" "Cardano/Wallet/Primitive/Delegation/StateSpec" "Cardano/Wallet/Primitive/AddressDiscoverySpec" - "Cardano/Wallet/Primitive/CoinSelectionSpec" - "Cardano/Wallet/Primitive/CoinSelection/BalanceSpec" - "Cardano/Wallet/Primitive/CoinSelection/CollateralSpec" "Cardano/Wallet/Primitive/CollateralSpec" "Cardano/Wallet/Primitive/MigrationSpec" "Cardano/Wallet/Primitive/Migration/PlanningSpec"