Skip to content

Commit

Permalink
decouple deposits from 'estimateFee'
Browse files Browse the repository at this point in the history
  Fees and deposits are closely related but that aren't the same thing. So it's better to keep the fee estimation about fees, and leave deposits out of it.
  • Loading branch information
KtorZ committed Jan 27, 2021
1 parent 0a99a26 commit 09b9b14
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
33 changes: 25 additions & 8 deletions lib/core/src/Cardano/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1987,27 +1987,44 @@ data FeeEstimation = FeeEstimation
-- ^ Most coin selections will result in a fee higher than this.
, estMaxFee :: Word64
-- ^ Most coin selections will result in a fee lower than this.
, deposit :: Maybe Word64
-- ^ Deposit if stake key was registered,
} deriving (Show, Eq, Generic)

instance NFData FeeEstimation

-- | Calculate the minimum deposit necessary if a given wallet wanted to
-- delegate to a pool. Said differently, this return either 0, or the value of
-- the key deposit protocol parameters if the wallet has no registered stake
-- key.
calcMinimumDeposit
:: forall ctx s k.
( HasDBLayer s k ctx
)
=> ctx
-> WalletId
-> ExceptT ErrNoSuchWallet IO Coin
calcMinimumDeposit ctx wid = db & \DBLayer{..} -> do
mapExceptT atomically (isStakeKeyRegistered $ PrimaryKey wid) >>= \case
True ->
pure $ Coin 0
False ->
stakeKeyDeposit <$> readWalletProtocolParameters @ctx @s @k ctx wid
where
db = ctx ^. dbLayer @s @k

-- | Estimate the transaction fee for a given coin selection algorithm by
-- repeatedly running it (100 times) and collecting the results. In the returned
-- 'FeeEstimation', the minimum fee is that which 90% of the sampled fees are
-- greater than. The maximum fee is the highest fee observed in the samples.
estimateFeeForCoinSelection
estimateFee
:: forall m err. Monad m
=> Maybe Word64
-> ExceptT err m Fee
=> ExceptT err m Coin
-> ExceptT err m FeeEstimation
estimateFeeForCoinSelection deposit'
estimateFee
= fmap deciles
. handleErrors
. replicateM repeats
. runExceptT
. fmap getFee
. fmap unCoin
where
-- Use method R-8 from to get top 90%.
-- https://en.wikipedia.org/wiki/Quantile#Estimating_quantiles_from_a_sample
Expand All @@ -2017,7 +2034,7 @@ estimateFeeForCoinSelection deposit'
. quantiles medianUnbiased (V.fromList [1, 10]) 10
. V.fromList
. map fromIntegral
mkFeeEstimation [a,b] = FeeEstimation a b deposit'
mkFeeEstimation [a,b] = FeeEstimation a b
mkFeeEstimation _ = error "estimateFeeForCoinSelection: impossible"

-- Remove failed coin selections from samples. Unless they all failed, in
Expand Down
12 changes: 6 additions & 6 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1507,11 +1507,6 @@ mkApiTransactionFromInfo ti (TransactionInfo txid fee ins outs ws meta depth txt
where
drop2nd (a,_,c) = (a,c)

apiFee :: FeeEstimation -> ApiFee
apiFee (FeeEstimation estMin estMax deposit) =
ApiFee (qty estMin) (qty estMax) (qty $ fromMaybe 0 deposit)
where qty = Quantity . fromIntegral

postTransactionFee
:: forall ctx s k n.
( ctx ~ ApiLayer s k
Expand Down Expand Up @@ -1542,7 +1537,7 @@ postTransactionFee ctx (ApiT wid) body = do
liftIO $ W.readNextWithdrawal @_ @s @k wrk wid wdrl

fee <- liftHandler $ W.estimateFeeForPayment @_ @s @k wrk wid outs wdrl md
pure $ apiFee fee
pure $ mkApiFee fee Nothing

joinStakePool
:: forall ctx s n k.
Expand Down Expand Up @@ -2092,6 +2087,11 @@ mkApiCoin
-> Quantity "lovelace" Natural
mkApiCoin (Coin c) = Quantity $ fromIntegral c

mkApiFee :: Maybe Coin -> FeeEstimation -> ApiFee
mkApiFee deposit (FeeEstimation estMin estMax) =
ApiFee (qty estMin) (qty estMax) (qty $ unCoin $ fromMaybe (Coin 0) deposit)
where qty = Quantity . fromIntegral

mkApiWithdrawal
:: forall (n :: NetworkDiscriminant). ()
=> (RewardAccount, Coin)
Expand Down

0 comments on commit 09b9b14

Please sign in to comment.