Skip to content

Commit

Permalink
add withdrawal on each payment transaction
Browse files Browse the repository at this point in the history
We could make it slightly smarter here and requires that the withdrawal is only requested when the balance is somewhat sufficient.
Sufficient would mean, bigger than the cost of adding it. Indeed, adding a withdrawal would only make sense if the cost of adding it
isn't greater to its value.
  • Loading branch information
KtorZ committed Jul 3, 2020
1 parent 2f11dcc commit 6d33031
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 19 deletions.
23 changes: 12 additions & 11 deletions lib/core/src/Cardano/Wallet.hs
Expand Up @@ -1102,11 +1102,12 @@ selectCoinsForPayment
=> ctx
-> WalletId
-> NonEmpty TxOut
-> Quantity "lovelace" Word64
-> ExceptT (ErrSelectForPayment e) IO CoinSelection
selectCoinsForPayment ctx wid recipients = do
selectCoinsForPayment ctx wid recipients withdrawal = do
(utxo, txp) <- withExceptT ErrSelectForPaymentNoSuchWallet $
selectCoinsSetup @ctx @s @k ctx wid
selectCoinsForPaymentFromUTxO @ctx @t @k @e ctx utxo txp recipients
selectCoinsForPaymentFromUTxO @ctx @t @k @e ctx utxo txp recipients withdrawal

-- | Retrieve wallet data which is needed for all types of coin selections.
selectCoinsSetup
Expand All @@ -1132,16 +1133,17 @@ selectCoinsForPaymentFromUTxO
-> W.UTxO
-> W.TxParameters
-> NonEmpty TxOut
-> Quantity "lovelace" Word64
-> ExceptT (ErrSelectForPayment e) IO CoinSelection
selectCoinsForPaymentFromUTxO ctx utxo txp recipients = do
selectCoinsForPaymentFromUTxO ctx utxo txp recipients (Quantity withdrawal) = do
lift . traceWith tr $ MsgPaymentCoinSelectionStart utxo txp recipients
(sel, utxo') <- withExceptT ErrSelectForPaymentCoinSelection $ do
let opts = coinSelOpts tl (txp ^. #getTxMaxSize)
CoinSelection.random opts recipients utxo
lift . traceWith tr $ MsgPaymentCoinSelection sel
let feePolicy = feeOpts tl Nothing (txp ^. #getFeePolicy)
withExceptT ErrSelectForPaymentFee $ do
balancedSel <- adjustForFee feePolicy utxo' sel
balancedSel <- adjustForFee feePolicy utxo' (sel { withdrawal })
lift . traceWith tr $ MsgPaymentCoinSelectionAdjusted balancedSel
pure balancedSel
where
Expand Down Expand Up @@ -1264,12 +1266,13 @@ estimateFeeForPayment
=> ctx
-> WalletId
-> NonEmpty TxOut
-> Quantity "lovelace" Word64
-> ExceptT (ErrSelectForPayment e) IO FeeEstimation
estimateFeeForPayment ctx wid recipients = do
estimateFeeForPayment ctx wid recipients withdrawal = do
(utxo, txp) <- withExceptT ErrSelectForPaymentNoSuchWallet $
selectCoinsSetup @ctx @s @k ctx wid
let selectCoins =
selectCoinsForPaymentFromUTxO @ctx @t @k @e ctx utxo txp recipients
selectCoinsForPaymentFromUTxO @ctx @t @k @e ctx utxo txp recipients withdrawal
estimateFeeForCoinSelection $ (Fee . feeBalance <$> selectCoins)
`catchE` handleCannotCover utxo recipients

Expand Down Expand Up @@ -1385,9 +1388,6 @@ signTx ctx wid pwd (UnsignedTx inpsNE outsNE) = db & \DBLayer{..} -> do
outs = NE.toList outsNE

-- | Makes a fully-resolved coin selection for the given set of payments.
--
-- TODO
-- This function completely disregard deposit and withdrawals.
selectCoinsExternal
:: forall ctx s t k e.
( GenChange s
Expand All @@ -1400,10 +1400,11 @@ selectCoinsExternal
-> WalletId
-> ArgGenChange s
-> NonEmpty TxOut
-> Quantity "lovelace" Word64
-> ExceptT (ErrSelectCoinsExternal e) IO UnsignedTx
selectCoinsExternal ctx wid argGenChange payments = do
selectCoinsExternal ctx wid argGenChange payments withdrawal = do
cs <- withExceptT ErrSelectCoinsExternalUnableToMakeSelection $
selectCoinsForPayment @ctx @s @t @k @e ctx wid payments
selectCoinsForPayment @ctx @s @t @k @e ctx wid payments withdrawal
cs' <- db & \DBLayer{..} ->
withExceptT ErrSelectCoinsExternalNoSuchWallet $
mapExceptT atomically $ do
Expand Down
21 changes: 13 additions & 8 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Expand Up @@ -1037,11 +1037,13 @@ selectCoins
-> ApiT WalletId
-> ApiSelectCoinsData n
-> Handler (ApiCoinSelection n)
selectCoins ctx genChange (ApiT wid) body =
selectCoins ctx gen (ApiT wid) body =
fmap mkApiCoinSelection
$ withWorkerCtx ctx wid liftE liftE
$ \wrk -> liftHandler $ W.selectCoinsExternal @_ @s @t @k wrk wid genChange
$ coerceCoin <$> body ^. #payments
$ withWorkerCtx ctx wid liftE liftE
$ \wrk -> do
withdrawal <- liftIO $ W.fetchRewardBalance @_ @s @k wrk wid
let outs = coerceCoin <$> body ^. #payments
liftHandler $ W.selectCoinsExternal @_ @s @t @k wrk wid gen outs withdrawal

{-------------------------------------------------------------------------------
Addresses
Expand Down Expand Up @@ -1126,8 +1128,9 @@ postTransaction ctx genChange (ApiT wid) body = do
let outs = coerceCoin <$> (body ^. #payments)
let pwd = coerce $ getApiT $ body ^. #passphrase

selection <- withWorkerCtx ctx wid liftE liftE $ \wrk -> liftHandler $
W.selectCoinsForPayment @_ @s @t wrk wid outs
selection <- withWorkerCtx ctx wid liftE liftE $ \wrk -> do
withdrawal <- liftIO $ W.fetchRewardBalance @_ @s @k wrk wid
liftHandler $ W.selectCoinsForPayment @_ @s @t wrk wid outs withdrawal

(tx, meta, time, wit) <- withWorkerCtx ctx wid liftE liftE $ \wrk -> liftHandler $
W.signPayment @_ @s @t @k wrk wid genChange pwd selection
Expand Down Expand Up @@ -1212,8 +1215,10 @@ postTransactionFee
-> Handler ApiFee
postTransactionFee ctx (ApiT wid) body = do
let outs = coerceCoin <$> (body ^. #payments)
withWorkerCtx ctx wid liftE liftE $ \wrk -> liftHandler
(apiFee <$> W.estimateFeeForPayment @_ @s @t @k wrk wid outs)
withWorkerCtx ctx wid liftE liftE $ \wrk -> do
withdrawal <- liftIO $ W.fetchRewardBalance @_ @s @k wrk wid
fee <- liftHandler $ W.estimateFeeForPayment @_ @s @t @k wrk wid outs withdrawal
pure $ apiFee fee

joinStakePool
:: forall ctx s t n k.
Expand Down

0 comments on commit 6d33031

Please sign in to comment.