Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide shared context for common coin selection types. #3165

Merged
merged 13 commits into from
Mar 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/core/cardano-wallet-core.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ library
Cardano.Wallet.CoinSelection.Internal
Cardano.Wallet.CoinSelection.Internal.Balance
Cardano.Wallet.CoinSelection.Internal.Collateral
Cardano.Wallet.CoinSelection.Internal.Context
Cardano.Wallet.Compat
Cardano.Wallet.DB
Cardano.Wallet.DB.Checkpoints
Expand Down
42 changes: 17 additions & 25 deletions lib/core/src/Cardano/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ import Cardano.Wallet.CoinSelection
, SelectionSkeleton (..)
, SelectionStrategy (..)
, UnableToConstructChangeError (..)
, WalletSelectionContext
, WalletUTxO (..)
, emptySkeleton
, makeSelectionReportDetailed
, makeSelectionReportSummarized
Expand Down Expand Up @@ -561,6 +563,7 @@ import UnliftIO.MVar

import qualified Cardano.Api.Shelley as Cardano
import qualified Cardano.Crypto.Wallet as CC
import qualified Cardano.Wallet.CoinSelection as CS
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
Expand Down Expand Up @@ -1469,7 +1472,7 @@ balanceTransaction
-> ArgGenChange s
-> (W.ProtocolParameters, Cardano.ProtocolParameters)
-> TimeInterpreter (Either PastHorizonException)
-> (UTxOIndex InputId, Wallet s, Set Tx)
-> (UTxOIndex WalletUTxO, Wallet s, Set Tx)
-> PartialTx
-> ExceptT ErrBalanceTx m SealedTx
balanceTransaction
Expand All @@ -1490,7 +1493,8 @@ balanceTransaction

(delta, extraInputs, extraCollateral, extraOutputs) <- do
let externalSelectedUtxo = UTxOIndex.fromSequence $
map (\(i, TxOut a b,_datumHash) -> ((i, a), b)) externalInputs
map (\(i, TxOut a b,_datumHash) -> (WalletUTxO i a, b))
externalInputs

let utxoAvailableForInputs = UTxOSelection.fromIndexPair
(internalUtxoAvailable, externalSelectedUtxo)
Expand Down Expand Up @@ -1608,7 +1612,7 @@ balanceTransaction
Just x -> pure x
Nothing -> throwE $ ErrBalanceTxUpdateError ErrByronTxNotSupported
where
utxo = inputMapToUTxO $ UTxOIndex.toMap internalUtxoAvailable
utxo = CS.toExternalUTxOMap $ UTxOIndex.toMap internalUtxoAvailable

assembleTransaction
:: TxUpdate
Expand Down Expand Up @@ -1883,10 +1887,11 @@ readWalletUTxOIndex
:: forall ctx s k. HasDBLayer IO s k ctx
=> ctx
-> WalletId
-> ExceptT ErrNoSuchWallet IO (UTxOIndex InputId, Wallet s, Set Tx)
-> ExceptT ErrNoSuchWallet IO (UTxOIndex WalletUTxO, Wallet s, Set Tx)
readWalletUTxOIndex ctx wid = do
(cp, _, pending) <- readWallet @ctx @s @k ctx wid
let utxo = UTxOIndex.fromMap $ utxoToInputMap $ availableUTxO @s pending cp
let utxo = UTxOIndex.fromMap $
CS.toInternalUTxOMap $ availableUTxO @s pending cp
return (utxo, cp, pending)

-- | Calculate the minimum coin values required for a bunch of specified
Expand All @@ -1909,29 +1914,15 @@ calcMinimumCoinValues ctx outs = do
nl = ctx ^. networkLayer
tl = ctx ^. transactionLayer @k

-- TODO: ADP-1448:
--
-- Replace this type synonym with a type parameter on types that use it.
--
type InputId = (TxIn, Address)

utxoToInputMap :: UTxO -> Map InputId TokenBundle
utxoToInputMap =
Map.fromList . fmap (\(i, TxOut a b) -> ((i, a), b)) . Map.toList . unUTxO

inputMapToUTxO :: Map InputId TokenBundle -> UTxO
inputMapToUTxO =
UTxO . Map.fromList . fmap (\((i, a), b) -> (i, TxOut a b)) . Map.toList

-- | Parameters for the 'selectAssets' function.
--
data SelectAssetsParams s result = SelectAssetsParams
{ outputs :: [TxOut]
, pendingTxs :: Set Tx
, randomSeed :: Maybe StdGenSeed
, txContext :: TransactionCtx
, utxoAvailableForCollateral :: Map InputId TokenBundle
, utxoAvailableForInputs :: UTxOSelection InputId
, utxoAvailableForCollateral :: Map WalletUTxO TokenBundle
, utxoAvailableForInputs :: UTxOSelection WalletUTxO
, wallet :: Wallet s
, selectionStrategy :: SelectionStrategy
-- ^ Specifies which selection strategy to use. See 'SelectionStrategy'.
Expand Down Expand Up @@ -1971,7 +1962,7 @@ selectAssets
selectAssets ctx pp params transform = do
guardPendingWithdrawal
lift $ traceWith tr $ MsgSelectionStart
(inputMapToUTxO
(CS.toExternalUTxOMap
$ UTxOSelection.availableMap
$ params ^. #utxoAvailableForInputs)
(params ^. #outputs)
Expand Down Expand Up @@ -3269,10 +3260,11 @@ data ErrCreateMigrationPlan
deriving (Generic, Eq, Show)

data ErrSelectAssets
= ErrSelectAssetsPrepareOutputsError SelectionOutputError
= ErrSelectAssetsPrepareOutputsError
(SelectionOutputError WalletSelectionContext)
| ErrSelectAssetsNoSuchWallet ErrNoSuchWallet
| ErrSelectAssetsAlreadyWithdrawing Tx
| ErrSelectAssetsSelectionError (SelectionError InputId)
| ErrSelectAssetsSelectionError (SelectionError WalletSelectionContext)
deriving (Generic, Eq, Show)

data ErrStakePoolDelegation
Expand Down Expand Up @@ -3422,7 +3414,7 @@ data WalletFollowLog
-- | Log messages from API server actions running in a wallet worker context.
data WalletLog
= MsgSelectionStart UTxO [TxOut]
| MsgSelectionError (SelectionError InputId)
| MsgSelectionError (SelectionError WalletSelectionContext)
| MsgSelectionReportSummarized SelectionReportSummarized
| MsgSelectionReportDetailed SelectionReportDetailed
| MsgMigrationUTxOBefore UTxOStatistics
Expand Down
15 changes: 10 additions & 5 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ import Cardano.Wallet.CoinSelection
, SelectionOutputSizeExceedsLimitError (..)
, SelectionOutputTokenQuantityExceedsLimitError (..)
, SelectionStrategy (..)
, WalletSelectionContext
, balanceMissing
, selectionDelta
, shortfall
Expand Down Expand Up @@ -4319,14 +4320,16 @@ instance IsServerError (ErrInvalidDerivationIndex 'Soft level) where
, "between ", pretty minIx, " and ", pretty maxIx, " without a suffix."
]

instance IsServerError SelectionOutputError where
instance IsServerError (SelectionOutputError WalletSelectionContext) where
toServerError = \case
SelectionOutputSizeExceedsLimit e ->
toServerError e
SelectionOutputTokenQuantityExceedsLimit e ->
toServerError e

instance IsServerError SelectionOutputSizeExceedsLimitError where
instance IsServerError
(SelectionOutputSizeExceedsLimitError WalletSelectionContext)
where
toServerError e = apiError err403 OutputTokenBundleSizeExceedsLimit $
mconcat
[ "One of the outputs you've specified contains too many assets. "
Expand All @@ -4340,7 +4343,9 @@ instance IsServerError SelectionOutputSizeExceedsLimitError where
where
output = view #outputThatExceedsLimit e

instance IsServerError SelectionOutputTokenQuantityExceedsLimitError where
instance IsServerError
(SelectionOutputTokenQuantityExceedsLimitError WalletSelectionContext)
where
toServerError e = apiError err403 OutputTokenQuantityExceedsLimit $ mconcat
[ "One of the token quantities you've specified is greater than the "
, "maximum quantity allowed in a single transaction output. Try "
Expand Down Expand Up @@ -4391,7 +4396,7 @@ instance IsServerError ErrSelectAssets where
ErrSelectAssetsSelectionError (SelectionOutputErrorOf e) ->
toServerError e

instance IsServerError (SelectionBalanceError (TxIn, Address)) where
instance IsServerError (SelectionBalanceError WalletSelectionContext) where
toServerError = \case
BalanceInsufficient e ->
apiError err403 NotEnoughMoney $ mconcat
Expand Down Expand Up @@ -4434,7 +4439,7 @@ instance IsServerError (SelectionBalanceError (TxIn, Address)) where
, "required in order to create a transaction."
]

instance IsServerError (SelectionCollateralError (TxIn, Address)) where
instance IsServerError (SelectionCollateralError WalletSelectionContext) where
toServerError e =
apiError err403 InsufficientCollateral $ T.unwords
[ "I'm unable to create this transaction because the balance"
Expand Down
Loading