Skip to content

Commit

Permalink
Replace unsafe function coinQuantity.
Browse files Browse the repository at this point in the history
This function is unsafe because `Coin` is now defined in terms of `Natural`.

We replace this function with a pair of functions:

- Coin.toQuantity        :: Integral i => Coin -> Maybe (Quantity n i)
- Coin.unsafeToQuantity  :: Integral i => Coin ->        Quantity n i
  • Loading branch information
jonathanknowles committed Nov 23, 2021
1 parent b5888d5 commit e7ff63d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
7 changes: 4 additions & 3 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ import Cardano.Wallet.Primitive.Types
import Cardano.Wallet.Primitive.Types.Address
( Address (..), AddressState (..) )
import Cardano.Wallet.Primitive.Types.Coin
( Coin (..), coinQuantity )
( Coin (..) )
import Cardano.Wallet.Primitive.Types.Hash
( Hash (..) )
import Cardano.Wallet.Primitive.Types.Redeemer
Expand Down Expand Up @@ -596,6 +596,7 @@ import qualified Cardano.Wallet.Primitive.AddressDerivation.Icarus as Icarus
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
import qualified Cardano.Wallet.Primitive.Types.TokenMap as TokenMap
import qualified Cardano.Wallet.Primitive.Types.Tx as W
Expand Down Expand Up @@ -3241,8 +3242,8 @@ mkApiFee :: Maybe Coin -> [Coin] -> FeeEstimation -> ApiFee
mkApiFee mDeposit minCoins (FeeEstimation estMin estMax) = ApiFee
{ estimatedMin = qty estMin
, estimatedMax = qty estMax
, minimumCoins = coinQuantity <$> minCoins
, deposit = coinQuantity $ fromMaybe (Coin 0) mDeposit
, minimumCoins = Coin.unsafeToQuantity <$> minCoins
, deposit = Coin.unsafeToQuantity $ fromMaybe (Coin 0) mDeposit
}
where
qty = Quantity . fromIntegral
Expand Down
36 changes: 30 additions & 6 deletions lib/core/src/Cardano/Wallet/Primitive/Types/Coin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ module Cardano.Wallet.Primitive.Types.Coin
-- * Conversions (Safe)
, fromIntegral
, fromWord64
, toQuantity
, toWord64

-- * Conversions (Unsafe)
, unsafeFromIntegral
, unsafeToQuantity
, unsafeToWord64

-- * Compatibility
, coinQuantity
, coinToInteger
, coinToNatural
, unsafeNaturalToCoin
Expand Down Expand Up @@ -143,6 +144,14 @@ fromIntegral i = Coin <$> intCastMaybe i
fromWord64 :: Word64 -> Coin
fromWord64 = Coin . intCast

-- | Converts a 'Coin' to a 'Quantity'.
--
-- Returns 'Nothing' if the given value does not fit within the bounds of
-- the target type.
--
toQuantity :: (Bits i, Integral i) => Coin -> Maybe (Quantity n i)
toQuantity (Coin c) = Quantity <$> intCastMaybe c

-- | Converts a 'Coin' to a 'Word64' value.
--
-- Returns 'Nothing' if the given value does not fit within the bounds of a
Expand Down Expand Up @@ -175,6 +184,26 @@ unsafeFromIntegral i = fromMaybe onError (fromIntegral i)
, "is not a natural number."
]

-- | Converts a 'Coin' to a 'Quantity'.
--
-- Callers of this function must take responsibility for checking that the
-- given value will fit within the bounds of the target type.
--
-- Produces a run-time error if the given value is out of bounds.
--
unsafeToQuantity
:: HasCallStack
=> (Bits i, Integral i)
=> Coin
-> Quantity n i
unsafeToQuantity c = fromMaybe onError (toQuantity c)
where
onError = error $ unwords
[ "Coin.unsafeToQuantity:"
, show c
, "does not fit within the bounds of the target type."
]

-- | Converts a 'Coin' to a 'Word64' value.
--
-- Callers of this function must take responsibility for checking that the
Expand All @@ -195,11 +224,6 @@ unsafeToWord64 c = fromMaybe onError (toWord64 c)
Compatibility
-------------------------------------------------------------------------------}

-- | Compatibility function to use while 'Quantity' is still used in non-API
-- parts of the code.
coinQuantity :: Integral a => Coin -> Quantity n a
coinQuantity (Coin n) = Quantity (Prelude.fromIntegral n)

coinToInteger :: Coin -> Integer
coinToInteger = Prelude.fromIntegral . unCoin

Expand Down

0 comments on commit e7ff63d

Please sign in to comment.