Skip to content

Commit

Permalink
Change type of extraCoinSource from Maybe Coin to Coin.
Browse files Browse the repository at this point in the history
The following values of `extraCoinSource` are treated identically by the
coin selection algorithm:

    - Nothing
    - Just (Coin 0)

Therefore, using the type `Maybe Coin` doesn't really make sense here.

If a caller wants to encode the lack of an extra coin source, they can
just supply `Coin 0`.
  • Loading branch information
jonathanknowles committed Sep 16, 2021
1 parent f40d178 commit 6ca7bb1
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 35 deletions.
5 changes: 1 addition & 4 deletions lib/core/src/Cardano/Wallet.hs
Expand Up @@ -2040,10 +2040,7 @@ migrationPlanToSelectionWithdrawals plan rewardWithdrawal outputAddressesToCycle
-- and have the transaction layer calculate the actual fee based only
-- on the contents of that record.
--
extraCoinSource =
if (view #rewardWithdrawal migrationSelection) > Coin 0
then Just (view #rewardWithdrawal migrationSelection)
else Nothing
extraCoinSource = view #rewardWithdrawal migrationSelection

withdrawal =
if (view #rewardWithdrawal migrationSelection) > Coin 0
Expand Down
6 changes: 4 additions & 2 deletions lib/core/src/Cardano/Wallet/Primitive/CoinSelection.hs
Expand Up @@ -38,7 +38,7 @@ import Cardano.Wallet.Primitive.CoinSelection.Balance
import Cardano.Wallet.Primitive.Types.Address
( Address )
import Cardano.Wallet.Primitive.Types.Coin
( Coin )
( Coin (..) )
import Cardano.Wallet.Primitive.Types.TokenBundle
( TokenBundle )
import Cardano.Wallet.Primitive.Types.TokenMap
Expand All @@ -63,6 +63,8 @@ import Data.Generics.Labels
()
import Data.List.NonEmpty
( NonEmpty (..) )
import Data.Maybe
( fromMaybe )
import Data.Word
( Word16 )
import GHC.Generics
Expand Down Expand Up @@ -112,7 +114,7 @@ performSelection selectionConstraints selectionParams =
Balance.SelectionParams
{ assetsToBurn
, assetsToMint
, extraCoinSource = rewardWithdrawal
, extraCoinSource = fromMaybe (Coin 0) rewardWithdrawal
, outputsToCover = preparedOutputsToCover
, selectionLimit =
computeSelectionLimit $ F.toList preparedOutputsToCover
Expand Down
26 changes: 13 additions & 13 deletions lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Balance.hs
Expand Up @@ -227,8 +227,8 @@ data SelectionParams = SelectionParams
:: !SelectionLimit
-- ^ Specifies a limit to be adhered to when performing selection.
, extraCoinSource
:: !(Maybe Coin)
-- ^ An optional extra source of ada.
:: !Coin
-- ^ An extra source of ada.
, assetsToMint
:: !TokenMap
-- ^ Assets to mint: these provide input value to a transaction.
Expand Down Expand Up @@ -287,7 +287,7 @@ computeUTxOBalanceRequired params =
balanceIn =
TokenBundle.fromTokenMap (view #assetsToMint params)
`TokenBundle.add`
F.foldMap TokenBundle.fromCoin (view #extraCoinSource params)
TokenBundle.fromCoin (view #extraCoinSource params)
balanceOut =
TokenBundle.fromTokenMap (view #assetsToBurn params)
`TokenBundle.add`
Expand Down Expand Up @@ -386,8 +386,8 @@ data SelectionResult change = SelectionResult
:: !(NonEmpty (TxIn, TxOut))
-- ^ A (non-empty) list of inputs selected from 'utxoAvailable'.
, extraCoinSource
:: !(Maybe Coin)
-- ^ An optional extra source of ada.
:: !Coin
-- ^ An extra source of ada.
, outputsCovered
:: ![TxOut]
-- ^ A list of outputs covered.
Expand Down Expand Up @@ -459,7 +459,7 @@ selectionDeltaAllAssets result
balanceIn =
TokenBundle.fromTokenMap assetsToMint
`TokenBundle.add`
F.foldMap TokenBundle.fromCoin extraCoinSource
TokenBundle.fromCoin extraCoinSource
`TokenBundle.add`
F.foldMap (view #tokens . snd) inputsSelected
balanceOut =
Expand Down Expand Up @@ -924,7 +924,7 @@ data SelectionReportSummarized = SelectionReportSummarized
, totalAdaBalanceIn :: Coin
, totalAdaBalanceOut :: Coin
, adaBalanceOfSelectedInputs :: Coin
, adaBalanceOfExtraInput :: Coin
, adaBalanceOfExtraCoinSource :: Coin
, adaBalanceOfRequestedOutputs :: Coin
, adaBalanceOfGeneratedChangeOutputs :: Coin
, numberOfSelectedInputs :: Int
Expand Down Expand Up @@ -967,13 +967,13 @@ makeSelectionReportSummarized s = SelectionReportSummarized {..}
computedFee
= Coin.distance totalAdaBalanceIn totalAdaBalanceOut
totalAdaBalanceIn
= adaBalanceOfSelectedInputs <> adaBalanceOfExtraInput
= adaBalanceOfSelectedInputs <> adaBalanceOfExtraCoinSource
totalAdaBalanceOut
= adaBalanceOfGeneratedChangeOutputs <> adaBalanceOfRequestedOutputs
adaBalanceOfSelectedInputs
= F.foldMap (view (#tokens . #coin) . snd) $ view #inputsSelected s
adaBalanceOfExtraInput
= F.fold (view #extraCoinSource s)
adaBalanceOfExtraCoinSource
= view #extraCoinSource s
adaBalanceOfGeneratedChangeOutputs
= F.foldMap (view #coin) $ view #changeGenerated s
adaBalanceOfRequestedOutputs
Expand Down Expand Up @@ -1265,8 +1265,8 @@ data MakeChangeCriteria minCoinFor bundleSizeAssessor = MakeChangeCriteria
-- - getCoin (fold changeBundles)
--
-- This typically captures fees plus key deposits.
, extraCoinSource :: Maybe Coin
-- ^ An optional extra source of ada.
, extraCoinSource :: Coin
-- ^ An extra source of ada.
, inputBundles :: NonEmpty TokenBundle
-- ^ Token bundles of selected inputs.
, outputBundles :: NonEmpty TokenBundle
Expand Down Expand Up @@ -1464,7 +1464,7 @@ makeChange criteria
totalInputValue :: TokenBundle
totalInputValue =
F.fold inputBundles
<> F.foldMap TokenBundle.fromCoin extraCoinSource
<> TokenBundle.fromCoin extraCoinSource
-- Mints represent extra inputs from "the void"
<> TokenBundle.fromTokenMap assetsToMint

Expand Down
Expand Up @@ -186,7 +186,6 @@ import Test.QuickCheck
, genericShrink
, ioProperty
, label
, oneof
, property
, shrinkList
, suchThat
Expand Down Expand Up @@ -625,7 +624,7 @@ genSelectionParams genUTxOIndex' = do
(1, UTxOIndex.size utxoAvailable `div` 8)
)
]
extraCoinSource <- oneof [ pure Nothing, Just <$> genCoin ]
extraCoinSource <- genCoin
(assetsToMint, assetsToBurn) <- genAssetsToMintAndBurn utxoAvailable
pure $ SelectionParams
{ outputsToCover
Expand Down Expand Up @@ -1526,7 +1525,7 @@ encodeBoundaryTestCriteria c = SelectionParams
, selectionLimit =
NoLimit
, extraCoinSource =
Nothing
Coin 0
, assetsToMint =
TokenMap.empty
, assetsToBurn =
Expand Down Expand Up @@ -1966,7 +1965,7 @@ isValidMakeChangeData p = (&&)
where
totalInputValue =
F.fold (inputBundles p)
<> (F.foldMap TokenBundle.fromCoin (view #extraCoinSource p))
<> (TokenBundle.fromCoin (view #extraCoinSource p))
<> TokenBundle.fromTokenMap (view #assetsToMint p)
totalOutputValue =
F.fold (outputBundles p)
Expand All @@ -1980,8 +1979,8 @@ genMakeChangeData = flip suchThat isValidMakeChangeData $ do
MakeChangeCriteria
<$> arbitrary
<*> pure NoBundleSizeLimit
<*> genCoin
<*> oneof [pure Nothing, Just <$> genCoinPositive]
<*> genRequiredCost
<*> genExtraCoinSource
<*> genTokenBundles inputBundleCount
<*> genTokenBundles outputBundleCount
<*> genAssetsToMint
Expand All @@ -1993,6 +1992,12 @@ genMakeChangeData = flip suchThat isValidMakeChangeData $ do
genAssetsToBurn :: Gen TokenMap
genAssetsToBurn = genTokenMapSmallRange

genExtraCoinSource :: Gen Coin
genExtraCoinSource = genCoin

genRequiredCost :: Gen Coin
genRequiredCost = genCoin

genTokenBundles :: Int -> Gen (NonEmpty TokenBundle)
genTokenBundles count = (:|)
<$> genTokenBundleSmallRangePositive
Expand All @@ -2015,7 +2020,7 @@ prop_makeChange_identity bundles = (===)
criteria = MakeChangeCriteria
{ minCoinFor = const (Coin 0)
, requiredCost = Coin 0
, extraCoinSource = Nothing
, extraCoinSource = Coin 0
, bundleSizeAssessor = mkBundleSizeAssessor NoBundleSizeLimit
, inputBundles = bundles
, outputBundles = bundles
Expand Down Expand Up @@ -2232,7 +2237,7 @@ prop_makeChange_success_delta p change =
]
totalInputValue =
F.fold (inputBundles p)
<> F.foldMap TokenBundle.fromCoin (view #extraCoinSource p)
<> TokenBundle.fromCoin (view #extraCoinSource p)
<> TokenBundle.fromTokenMap (view #assetsToMint p)
totalInputCoin =
TokenBundle.getCoin totalInputValue
Expand Down Expand Up @@ -2290,7 +2295,7 @@ prop_makeChange_fail_costTooBig p =
where
totalInputValue =
F.fold (inputBundles p)
<> F.foldMap TokenBundle.fromCoin (view #extraCoinSource p)
<> TokenBundle.fromCoin (view #extraCoinSource p)
<> TokenBundle.fromTokenMap (view #assetsToMint p)
totalOutputValue =
F.fold (outputBundles p)
Expand Down Expand Up @@ -2339,7 +2344,7 @@ prop_makeChange_fail_minValueTooBig p =
where
totalInputValue =
F.fold (inputBundles p)
<> F.foldMap TokenBundle.fromCoin (view #extraCoinSource p)
<> TokenBundle.fromCoin (view #extraCoinSource p)
<> TokenBundle.fromTokenMap (view #assetsToMint p)
totalOutputValue =
F.fold (outputBundles p)
Expand All @@ -2366,15 +2371,15 @@ unit_makeChange =
matrix =
-- Simple, only ada, should construct a single change output with 1 ada.
[ ( noMinCoin, noCost
, Nothing
, Coin 0
, b 2 [] :| []
, b 1 [] :| []
, Right [b 1 []]
)

-- Two outputs, no cost, changes are proportional, no extra assets
, ( noMinCoin, noCost
, Nothing
, Coin 0
, b 9 [(assetA, 9), (assetB, 6)] :| []
, b 2 [(assetA, 1)] :| [b 1 [(assetA, 2), (assetB, 3)]]
, Right
Expand All @@ -2386,7 +2391,7 @@ unit_makeChange =
-- Extra non-user-specified assets. Large assets end up in 'large'
-- bundles and small extra assets in smaller bundles.
, ( noMinCoin, noCost
, Nothing
, Coin 0
, b 1 [(assetA, 10), (assetC, 1)] :| [b 1 [(assetB, 2), (assetC, 8)]]
, b 1 [(assetA, 5)] :| [b 1 [(assetB, 1)]]
, Right
Expand Down
Expand Up @@ -816,7 +816,7 @@ binaryCalculationsSpec' era = describe ("calculateBinary - "+||era||+"") $ do
Right unsigned = mkUnsignedTx era slotNo cs md mempty [] fee
cs = SelectionResult
{ inputsSelected = NE.fromList inps
, extraCoinSource = Nothing
, extraCoinSource = Coin 0
, outputsCovered = outs
, changeGenerated = chgs
, utxoRemaining = UTxOIndex.empty
Expand Down Expand Up @@ -897,7 +897,7 @@ makeShelleyTx era testCase = Cardano.makeSignedTransaction addrWits unsigned
addrWits = map (mkShelleyWitness unsigned) pairs
cs = SelectionResult
{ inputsSelected = NE.fromList inps
, extraCoinSource = Nothing
, extraCoinSource = Coin 0
, outputsCovered = []
, changeGenerated = outs
, utxoRemaining = UTxOIndex.empty
Expand Down Expand Up @@ -933,7 +933,7 @@ makeByronTx era testCase = Cardano.makeSignedTransaction byronWits unsigned
byronWits = map (error "makeByronTx: broken") pairs -- TODO: [ADP-919]
cs = SelectionResult
{ inputsSelected = NE.fromList inps
, extraCoinSource = Nothing
, extraCoinSource = Coin 0
, outputsCovered = []
, changeGenerated = outs
, utxoRemaining = UTxOIndex.empty
Expand Down

0 comments on commit 6ca7bb1

Please sign in to comment.