Skip to content

Commit

Permalink
Merge #1191
Browse files Browse the repository at this point in the history
1191: compute payment fee as the difference between inputs/outputs r=KtorZ a=KtorZ

# Issue Number

<!-- Put here a reference to the issue this PR relates to and which requirements it tackles -->

#1150 

# Overview

<!-- Detail in a few bullet points the work accomplished in this PR -->

- [x] I have re-used the existing coin selection function and removing the need for an extra 'estimateFee' function in the core engine


# Comments

<!-- Additional comments or screenshots to attach if any -->

<!-- 
Don't forget to:

 ✓ Self-review your changes to make sure nothing unexpected slipped through
 ✓ Assign yourself to the PR
 ✓ Assign one or several reviewer(s)
 ✓ Once created, link this PR to its corresponding ticket
 ✓ Assign the PR to a corresponding milestone
 ✓ Acknowledge any changes required to the Wiki
-->


Co-authored-by: KtorZ <matthias.benkort@gmail.com>
  • Loading branch information
iohk-bors[bot] and KtorZ authored Dec 16, 2019
2 parents 09ff1dc + 08422b3 commit 9a4d4d0
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ spec = do
wSrc <- fixtureWalletWith ctx [feeMin `div` 2]
wDest <- emptyWallet ctx
addr:_ <- listAddresses ctx wDest
let amt = 1
let amt = 1 :: Natural

let destination = addr ^. #id
let payload = Json [json|{
Expand All @@ -950,7 +950,7 @@ spec = do
r <- request @ApiFee ctx (postTxFeeEp wSrc) Default payload
verify r
[ expectResponseCode HTTP.status202
, expectFieldBetween amount (feeMin - amt, feeMax + amt)
, expectFieldBetween amount (feeMin, feeMax)
]

it "TRANS_ESTIMATE_04 - Not enough money" $ \ctx -> do
Expand Down
32 changes: 0 additions & 32 deletions lib/core/src/Cardano/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,9 @@ module Cardano.Wallet
-- ** Payment
, selectCoinsExternal
, selectCoinsForPayment
, estimatePaymentFee
, signPayment
, ErrSelectCoinsExternal (..)
, ErrSelectForPayment (..)
, ErrEstimatePaymentFee (..)
, ErrSignPayment (..)
, ErrCoinSelection (..)
, ErrAdjustForFee (..)
Expand Down Expand Up @@ -865,30 +863,6 @@ selectCoinsForMigration ctx wid = do
where
tl = ctx ^. transactionLayer @t @k

-- | Estimate a transaction fee by automatically selecting inputs from
-- the wallet to cover the requested outputs.
estimatePaymentFee
:: forall ctx s t k e.
( HasTransactionLayer t k ctx
, HasDBLayer s k ctx
, e ~ ErrValidateSelection t
)
=> ctx
-> WalletId
-> NonEmpty TxOut
-> ExceptT (ErrEstimatePaymentFee e) IO Fee
estimatePaymentFee ctx wid recipients = do
(wal, _, pending) <- withExceptT ErrEstimatePaymentFeeNoSuchWallet $
readWallet @ctx @s @k ctx wid
let bp = blockchainParameters wal
let utxo = availableUTxO @s pending wal
(sel, _utxo') <- withExceptT ErrEstimatePaymentFeeCoinSelection $ do
let opts = coinSelOpts tl (bp ^. #getTxMaxSize)
CoinSelection.random opts recipients utxo
pure $ computeFee (bp ^. #getFeePolicy) $ estimateSize tl sel
where
tl = ctx ^. transactionLayer @t @k

-- | Augments the given outputs with new outputs. These new outputs corresponds
-- to change outputs to which new addresses are being assigned to. This updates
-- the wallet state as it needs to keep track of new pending change addresses.
Expand Down Expand Up @@ -1393,12 +1367,6 @@ data ErrSelectForPayment e
| ErrSelectForPaymentFee ErrAdjustForFee
deriving (Show, Eq)

-- | Errors that can occur when estimating transaction fees.
data ErrEstimatePaymentFee e
= ErrEstimatePaymentFeeNoSuchWallet ErrNoSuchWallet
| ErrEstimatePaymentFeeCoinSelection (ErrCoinSelection e)
deriving (Show, Eq)

-- | Errors that can occur when listing UTxO statistics.
newtype ErrListUTxOStatistics
= ErrListUTxOStatisticsNoSuchWallet ErrNoSuchWallet
Expand Down
29 changes: 14 additions & 15 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ import Cardano.Wallet
( ErrAdjustForFee (..)
, ErrCoinSelection (..)
, ErrDecodeSignedTx (..)
, ErrEstimatePaymentFee (..)
, ErrFetchRewards (..)
, ErrJoinStakePool (..)
, ErrListTransactions (..)
Expand Down Expand Up @@ -157,8 +156,6 @@ import Cardano.Wallet.Primitive.AddressDiscovery.Sequential
( SeqState (..), defaultAddressPoolGap, mkSeqState )
import Cardano.Wallet.Primitive.CoinSelection
( CoinSelection (..), changeBalance, feeBalance, inputBalance )
import Cardano.Wallet.Primitive.Fee
( Fee (..) )
import Cardano.Wallet.Primitive.Model
( Wallet, availableBalance, currentTip, getState, totalBalance )
import Cardano.Wallet.Primitive.Types
Expand Down Expand Up @@ -210,7 +207,7 @@ import Control.Monad
import Control.Monad.IO.Class
( MonadIO, liftIO )
import Control.Monad.Trans.Except
( ExceptT, except, throwE, withExceptT )
( ExceptT, catchE, except, throwE, withExceptT )
import Data.Aeson
( (.=) )
import Data.Function
Expand Down Expand Up @@ -802,13 +799,20 @@ postTransactionFee
-> Handler ApiFee
postTransactionFee ctx (ApiT wid) body = do
let outs = coerceCoin <$> (body ^. #payments)
(Fee fee) <- liftHandler $ withWorkerCtx ctx wid liftE $ \wrk ->
W.estimatePaymentFee @_ @s @t wrk wid outs
return ApiFee
{ amount = Quantity (fromIntegral fee)
}
liftHandler $ withWorkerCtx ctx wid liftE $ \wrk ->
(apiFee <$> W.selectCoinsForPayment @_ @s @t @k wrk wid outs)
`catchE` handleCannotCover wrk
where
liftE = throwE . ErrEstimatePaymentFeeNoSuchWallet
apiFee = ApiFee . Quantity . fromIntegral . feeBalance
liftE = throwE . ErrSelectForPaymentNoSuchWallet
handleCannotCover wrk = \case
ErrSelectForPaymentFee (ErrCannotCoverFee missing) -> do
(wallet, _, pending) <- withExceptT ErrSelectForPaymentNoSuchWallet $
W.readWallet wrk wid
let balance = availableBalance pending wallet
pure $ ApiFee $ Quantity $ fromIntegral missing + balance

e -> throwE e

{-------------------------------------------------------------------------------
Stake Pools
Expand Down Expand Up @@ -1600,11 +1604,6 @@ instance Buildable e => LiftHandler (ErrSelectForPayment e) where
ErrSelectForPaymentCoinSelection e -> handler e
ErrSelectForPaymentFee e -> handler e

instance Buildable e => LiftHandler (ErrEstimatePaymentFee e) where
handler = \case
ErrEstimatePaymentFeeNoSuchWallet e -> handler e
ErrEstimatePaymentFeeCoinSelection e -> handler e

instance LiftHandler ErrListUTxOStatistics where
handler = \case
ErrListUTxOStatisticsNoSuchWallet e -> handler e
Expand Down

0 comments on commit 9a4d4d0

Please sign in to comment.