Skip to content

Commit

Permalink
Merge #1859
Browse files Browse the repository at this point in the history
1859: install a query flag for driving withdrawals creation on Shelley tx r=KtorZ a=KtorZ



# Issue Number

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


# Overview

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

- b448b07
  📍 **install a query flag for driving withdrawals creation on Shelley transactions**
  Withdrawals currently occur by default, implicitely which turns out to
be very confusing for end-users (seeing their rewards balance disappear
freak them out, as well as transaction which seems much bigger than what
they requested).

# Comments

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

![Screenshot from 2020-07-06 07-53-08](https://user-images.githubusercontent.com/5680256/86563306-6c21a300-bf64-11ea-81b4-6ad2d53fee65.png)
<!-- 
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 <[email protected]>
  • Loading branch information
iohk-bors[bot] and KtorZ authored Jul 6, 2020
2 parents d4736bc + bcdf6a4 commit 1736316
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 28 deletions.
12 changes: 6 additions & 6 deletions lib/byron/src/Cardano/Wallet/Byron/Api/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ server byron icarus ntp =

transactions :: Server (Transactions n)
transactions =
(\_ _ -> throwError err501)
(\_ _ _ -> throwError err501)
:<|> (\_ _ _ _ -> throwError err501)
:<|> (\_ _ -> throwError err501)
:<|> (\_ _ _ -> throwError err501)
:<|> (\_ _ -> throwError err501)
:<|> (\_ _ -> throwError err501)

Expand Down Expand Up @@ -237,11 +237,11 @@ server byron icarus ntp =
(byron , do
let pwd = coerce (getApiT $ tx ^. #passphrase)
genChange <- rndStateChange byron wid pwd
postTransaction byron genChange wid tx
postTransaction byron genChange wid False tx
)
(icarus, do
let genChange k _ = paymentAddress @n k
postTransaction icarus genChange wid tx
postTransaction icarus genChange wid False tx
)
)
:<|>
Expand All @@ -251,8 +251,8 @@ server byron icarus ntp =
)
:<|>
(\wid tx -> withLegacyLayer wid
(byron , postTransactionFee byron wid tx)
(icarus, postTransactionFee icarus wid tx)
(byron , postTransactionFee byron wid False tx)
(icarus, postTransactionFee icarus wid False tx)
)
:<|> (\wid txid -> withLegacyLayer wid
(byron , deleteTransaction byron wid txid)
Expand Down
17 changes: 15 additions & 2 deletions lib/cli/src/Cardano/CLI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ import Cardano.Wallet.Api.Types
, ApiT (..)
, ApiTxId (ApiTxId)
, ApiWallet
, ApiWithdrawRewards (..)
, ByronWalletPostData (..)
, ByronWalletStyle (..)
, Iso8601Time (..)
Expand Down Expand Up @@ -689,6 +690,7 @@ data TransactionCreateArgs t = TransactionCreateArgs
{ _port :: Port "Wallet"
, _id :: WalletId
, _payments :: NonEmpty Text
, _withdrawRewards :: Bool
}

cmdTransactionCreate
Expand All @@ -704,7 +706,8 @@ cmdTransactionCreate mkTxClient mkWalletClient =
<$> portOption
<*> walletIdArgument
<*> fmap NE.fromList (some paymentOption)
exec (TransactionCreateArgs wPort wId wAddressAmounts) = do
<*> withdrawRewardsFlag
exec (TransactionCreateArgs wPort wId wAddressAmounts wWithdraw) = do
wPayments <- either (fail . getTextDecodingError) pure $
traverse (fromText @(AddressAmount Text)) wAddressAmounts
res <- sendRequest wPort $ getWallet mkWalletClient $ ApiT wId
Expand All @@ -714,6 +717,7 @@ cmdTransactionCreate mkTxClient mkWalletClient =
runClient wPort Aeson.encodePretty $ postTransaction
mkTxClient
(ApiT wId)
(ApiWithdrawRewards wWithdraw)
(Aeson.object
[ "payments" .= wPayments
, "passphrase" .= ApiT wPwd
Expand All @@ -735,7 +739,8 @@ cmdTransactionFees mkTxClient mkWalletClient =
<$> portOption
<*> walletIdArgument
<*> fmap NE.fromList (some paymentOption)
exec (TransactionCreateArgs wPort wId wAddressAmounts) = do
<*> withdrawRewardsFlag
exec (TransactionCreateArgs wPort wId wAddressAmounts wWithdraw) = do
wPayments <- either (fail . getTextDecodingError) pure $
traverse (fromText @(AddressAmount Text)) wAddressAmounts
res <- sendRequest wPort $ getWallet mkWalletClient $ ApiT wId
Expand All @@ -744,6 +749,7 @@ cmdTransactionFees mkTxClient mkWalletClient =
runClient wPort Aeson.encodePretty $ postTransactionFee
mkTxClient
(ApiT wId)
(ApiWithdrawRewards wWithdraw)
(Aeson.object [ "payments" .= wPayments ])
Left _ ->
handleResponse Aeson.encodePretty res
Expand Down Expand Up @@ -1335,6 +1341,13 @@ addressIdArgument :: Parser Text
addressIdArgument = argumentT $ mempty
<> metavar "ADDRESS"

-- | [--withdraw-rewards]
withdrawRewardsFlag :: Parser Bool
withdrawRewardsFlag = switch $ mempty
<> long "withdraw-rewards"
<> help "Withdraw rewards as change in this transaction, provided they \
\contribute positively to the balance."

-- | Helper for writing an option 'Parser' using a 'FromText' instance.
optionT :: FromText a => Mod OptionFields a -> Parser a
optionT = option (eitherReader fromTextS)
Expand Down
9 changes: 8 additions & 1 deletion lib/cli/test/unit/Cardano/CLISpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ spec = do

["transaction", "create", "--help"] `shouldShowUsage`
[ "Usage: transaction create [--port INT] WALLET_ID"
, " --payment PAYMENT"
, " --payment PAYMENT [--withdraw-rewards]"
, " Create and submit a new transaction."
, ""
, "Available options:"
Expand All @@ -261,10 +261,14 @@ spec = do
, " --payment PAYMENT address to send to and amount to send"
, " separated by @, e.g."
, " '<amount>@<address>'"
," --withdraw-rewards Withdraw rewards as change in this"
," transaction, provided they contribute"
," positively to the balance."
]

["transaction", "fees", "--help"] `shouldShowUsage`
[ "Usage: transaction fees [--port INT] WALLET_ID --payment PAYMENT"
, " [--withdraw-rewards]"
, " Estimate fees for a transaction."
, ""
, "Available options:"
Expand All @@ -274,6 +278,9 @@ spec = do
, " --payment PAYMENT address to send to and amount to send"
, " separated by @, e.g."
, " '<amount>@<address>'"
," --withdraw-rewards Withdraw rewards as change in this"
," transaction, provided they contribute"
," positively to the balance."
]

["transaction", "list", "--help"] `shouldShowUsage`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Cardano.Wallet.Api.Types
, ApiT (..)
, ApiTransaction
, ApiWallet
, ApiWithdrawRewards (..)
, DecodeAddress
, EncodeAddress
, WalletStyle (..)
Expand Down Expand Up @@ -184,10 +185,12 @@ spec = do
]
, "passphrase": #{fixturePassphrase}
}|]
request @(ApiTransaction n) ctx (Link.createTransaction @'Shelley w) Default (Json payload) >>= flip verify
[ expectField #amount (.> (Quantity coin))
, expectField (#direction . #getApiT) (`shouldBe` Outgoing)
]
request @(ApiTransaction n) ctx
(Link.createTransaction' @'Shelley w (ApiWithdrawRewards True))
Default (Json payload) >>= flip verify
[ expectField #amount (.> (Quantity coin))
, expectField (#direction . #getApiT) (`shouldBe` Outgoing)
]

-- Rewards are have been consumed.
eventually "Wallet has consumed rewards" $ do
Expand Down
2 changes: 2 additions & 0 deletions lib/core/src/Cardano/Wallet/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ type Transactions n =
type CreateTransaction n = "wallets"
:> Capture "walletId" (ApiT WalletId)
:> "transactions"
:> QueryFlag "withdrawRewards"
:> ReqBody '[JSON] (PostTransactionDataT n)
:> PostAccepted '[JSON] (ApiTransactionT n)

Expand All @@ -331,6 +332,7 @@ type GetTransaction n = "wallets"
type PostTransactionFee n = "wallets"
:> Capture "walletId" (ApiT WalletId)
:> "payment-fees"
:> QueryFlag "withdrawRewards"
:> ReqBody '[JSON] (PostTransactionFeeDataT n)
:> PostAccepted '[JSON] ApiFee

Expand Down
11 changes: 7 additions & 4 deletions lib/core/src/Cardano/Wallet/Api/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import Cardano.Wallet.Api.Types
, ApiUtxoStatistics
, ApiWallet (..)
, ApiWalletPassphrase
, ApiWithdrawRewards (..)
, ByronWalletPutPassphraseData (..)
, Iso8601Time (..)
, PostExternalTransactionData (..)
Expand Down Expand Up @@ -143,10 +144,12 @@ data TransactionClient = TransactionClient
-> ClientM [ApiTransactionT Aeson.Value]
, postTransaction
:: ApiT WalletId
-> ApiWithdrawRewards
-> PostTransactionDataT Aeson.Value
-> ClientM (ApiTransactionT Aeson.Value)
, postTransactionFee
:: ApiT WalletId
-> ApiWithdrawRewards
-> PostTransactionFeeDataT Aeson.Value
-> ClientM ApiFee
, postExternalTransaction
Expand Down Expand Up @@ -269,8 +272,8 @@ transactionClient =
in
TransactionClient
{ listTransactions = _listTransactions
, postTransaction = _postTransaction
, postTransactionFee = _postTransactionFee
, postTransaction = \wid -> _postTransaction wid . coerce
, postTransactionFee = \wid -> _postTransactionFee wid . coerce
, postExternalTransaction = _postExternalTransaction
, deleteTransaction = _deleteTransaction
, getTransaction = _getTransaction
Expand All @@ -293,8 +296,8 @@ byronTransactionClient =

in TransactionClient
{ listTransactions = _listTransactions
, postTransaction = _postTransaction
, postTransactionFee = _postTransactionFee
, postTransaction = \wid _ -> _postTransaction wid
, postTransactionFee = \wid _ -> _postTransactionFee wid
, postExternalTransaction = _postExternalTransaction
, deleteTransaction = _deleteTransaction
, getTransaction = _getTransaction
Expand Down
37 changes: 35 additions & 2 deletions lib/core/src/Cardano/Wallet/Api/Link.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ module Cardano.Wallet.Api.Link

-- * Transactions
, createTransaction
, createTransaction'
, listTransactions
, listTransactions'
, getTransactionFee
, getTransactionFee'
, deleteTransaction
, getTransaction

Expand Down Expand Up @@ -90,6 +92,7 @@ import Cardano.Wallet.Api.Types
( ApiPoolId (..)
, ApiT (..)
, ApiTxId (ApiTxId)
, ApiWithdrawRewards (..)
, Iso8601Time
, WalletStyle (..)
)
Expand Down Expand Up @@ -313,11 +316,26 @@ createTransaction
=> w
-> (Method, Text)
createTransaction w = discriminate @style
(endpoint @(Api.CreateTransaction Net) (wid &))
(endpoint @(Api.CreateTransaction Net) (($ False) . ($ wid)))
(endpoint @(Api.CreateByronTransaction Net) (wid &))
where
wid = w ^. typed @(ApiT WalletId)

createTransaction'
:: forall style w.
( HasType (ApiT WalletId) w
, Discriminate style
)
=> w
-> ApiWithdrawRewards
-> (Method, Text)
createTransaction' w (ApiWithdrawRewards withdraw) = discriminate @style
(endpoint @(Api.CreateTransaction Net) (($ withdraw) . ($ wid)))
(endpoint @(Api.CreateByronTransaction Net) (wid &))
where
wid = w ^. typed @(ApiT WalletId)


listTransactions
:: forall (style :: WalletStyle) w.
( Discriminate style
Expand Down Expand Up @@ -353,11 +371,26 @@ getTransactionFee
=> w
-> (Method, Text)
getTransactionFee w = discriminate @style
(endpoint @(Api.PostTransactionFee Net) (wid &))
(endpoint @(Api.PostTransactionFee Net) (($ False) . ($ wid)))
(endpoint @(Api.PostByronTransactionFee Net) (wid &))
where
wid = w ^. typed @(ApiT WalletId)

getTransactionFee'
:: forall style w.
( HasType (ApiT WalletId) w
, Discriminate style
)
=> w
-> ApiWithdrawRewards
-> (Method, Text)
getTransactionFee' w (ApiWithdrawRewards withdraw) = discriminate @style
(endpoint @(Api.PostTransactionFee Net) (($ withdraw) . ($ wid)))
(endpoint @(Api.PostByronTransactionFee Net) (wid &))
where
wid = w ^. typed @(ApiT WalletId)


deleteTransaction
:: forall (style :: WalletStyle) w t.
( Discriminate style
Expand Down
18 changes: 13 additions & 5 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,9 @@ selectCoins ctx gen (ApiT wid) body =
fmap mkApiCoinSelection
$ withWorkerCtx ctx wid liftE liftE
$ \wrk -> do
withdrawal <- liftIO $ W.readNextWithdrawal @_ @s @t @k wrk wid
-- TODO:
-- Allow representing withdrawals as part of external coin selections.
let withdrawal = Quantity 0
let outs = coerceCoin <$> body ^. #payments
liftHandler $ W.selectCoinsExternal @_ @s @t @k wrk wid gen outs withdrawal

Expand Down Expand Up @@ -1123,14 +1125,17 @@ postTransaction
=> ctx
-> ArgGenChange s
-> ApiT WalletId
-> Bool
-> PostTransactionData n
-> Handler (ApiTransaction n)
postTransaction ctx genChange (ApiT wid) body = do
postTransaction ctx genChange (ApiT wid) withdrawRewards body = do
let outs = coerceCoin <$> (body ^. #payments)
let pwd = coerce $ getApiT $ body ^. #passphrase

selection <- withWorkerCtx ctx wid liftE liftE $ \wrk -> do
withdrawal <- liftIO $ W.readNextWithdrawal @_ @s @t @k wrk wid
withdrawal <- if withdrawRewards
then liftIO $ W.readNextWithdrawal @_ @s @t @k wrk wid
else pure (Quantity 0)
liftHandler $ W.selectCoinsForPayment @_ @s @t wrk wid outs withdrawal

(tx, meta, time, wit) <- withWorkerCtx ctx wid liftE liftE $ \wrk -> liftHandler $
Expand Down Expand Up @@ -1212,12 +1217,15 @@ postTransactionFee
)
=> ctx
-> ApiT WalletId
-> Bool
-> PostTransactionFeeData n
-> Handler ApiFee
postTransactionFee ctx (ApiT wid) body = do
postTransactionFee ctx (ApiT wid) withdrawRewards body = do
let outs = coerceCoin <$> (body ^. #payments)
withWorkerCtx ctx wid liftE liftE $ \wrk -> do
withdrawal <- liftIO $ W.readNextWithdrawal @_ @s @t @k wrk wid
withdrawal <- if withdrawRewards
then liftIO $ W.readNextWithdrawal @_ @s @t @k wrk wid
else pure $ Quantity 0
fee <- liftHandler $ W.estimateFeeForPayment @_ @s @t @k wrk wid outs withdrawal
pure $ apiFee fee

Expand Down
4 changes: 4 additions & 0 deletions lib/core/src/Cardano/Wallet/Api/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ module Cardano.Wallet.Api.Types
, ApiPoolId (..)
, ApiWalletMigrationPostData (..)
, ApiWalletMigrationInfo (..)
, ApiWithdrawRewards (..)

-- * API Types (Byron)
, ApiByronWallet (..)
Expand Down Expand Up @@ -598,6 +599,9 @@ newtype ApiWalletMigrationInfo = ApiWalletMigrationInfo
{ migrationCost :: Quantity "lovelace" Natural
} deriving (Eq, Generic, Show)

newtype ApiWithdrawRewards = ApiWithdrawRewards Bool
deriving (Eq, Generic, Show)

-- | Error codes returned by the API, in the form of snake_cased strings
data ApiErrorCode
= NoSuchWallet
Expand Down
8 changes: 4 additions & 4 deletions lib/shelley/src/Cardano/Wallet/Shelley/Api/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,11 @@ server byron icarus shelley spl ntp =
(byron , do
let pwd = coerce (getApiT $ tx ^. #passphrase)
genChange <- rndStateChange byron wid pwd
postTransaction byron genChange wid tx
postTransaction byron genChange wid False tx
)
(icarus, do
let genChange k _ = paymentAddress @n k
postTransaction icarus genChange wid tx
postTransaction icarus genChange wid False tx
)
)
:<|>
Expand All @@ -276,8 +276,8 @@ server byron icarus shelley spl ntp =
)
:<|>
(\wid tx -> withLegacyLayer wid
(byron , postTransactionFee byron wid tx)
(icarus, postTransactionFee icarus wid tx)
(byron , postTransactionFee byron wid False tx)
(icarus, postTransactionFee icarus wid False tx)
)
:<|> (\wid txid -> withLegacyLayer wid
(byron , deleteTransaction byron wid txid)
Expand Down
Loading

0 comments on commit 1736316

Please sign in to comment.