Skip to content

Commit

Permalink
Tweak retrospective computation of change & outs
Browse files Browse the repository at this point in the history
Without this change integration tests would fail e.g. where:

```pseudo-code
constructTx
  paymentTo addr1 (0 ada)

  |
  |
  V

Tx
  output: addr1 (1 ada) -- min ada, set automatically
  output: addr2 (9 ada) -- change
```

as we'd believe both outputs in the resuling tx were change -- neither
of them exists in the original output list.

If there are 'n' outputs in the original unbalanced tx, we will with
this commit instead judge that the first 'n' are "outputs" and that the
ones after that are all change. While this makes assumptions about how
balanceTx appends outputs, it is more importantly ressilient to outputs
being modified, like with the `increaseZeroAdaOutputs` feature.
  • Loading branch information
Anviking authored and Unisay committed Nov 10, 2022
1 parent 18d5c5c commit 6b1f160
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2467,34 +2467,30 @@ constructTransaction

singleton x = [x]

toUnsignedTxChange initialOuts = \case
toUnsignedTxChange = \case
WalletOutput o ->
let address = getApiT (fst (o ^. #address))
derivationPath = fmap getApiT (o ^. #derivationPath)
coin = Coin.fromQuantity (o ^. #amount)
assets = getApiT (o ^. #assets)
txChange = TxChange address coin assets derivationPath
txOut = TxOut address (TokenBundle coin assets)
in
if txOut `L.notElem` initialOuts then Just txChange else Nothing
TxChange address coin assets derivationPath
ExternalOutput _ ->
Nothing
error "constructTx.toUnsignedTxChange: change should always be ours"

toUnsignedTxOut initialOuts = \case
toUnsignedTxOut = \case
WalletOutput o ->
let address = getApiT (fst (o ^. #address))
coin = Coin.fromQuantity (o ^. #amount)
assets = getApiT (o ^. #assets)
txOut = TxOut address (TokenBundle coin assets)
in
if txOut `L.elem` initialOuts then Just txOut else Nothing
TxOut address (TokenBundle coin assets)
ExternalOutput o ->
let address = getApiT (fst (o ^. #address))
coin = Coin.fromQuantity (o ^. #amount)
assets = getApiT (o ^. #assets)
txOut = TxOut address (TokenBundle coin assets)
in
if txOut `L.elem` initialOuts then Just txOut else Nothing
TxOut address (TokenBundle coin assets)

toUsignedTxWdrl p = \case
ApiWithdrawalGeneral (ApiT rewardAcc, _) amount Our ->
Expand Down Expand Up @@ -2523,9 +2519,17 @@ constructTransaction
, unsignedInputs =
mapMaybe toUnsignedTxInp (decodedTx ^. #inputs)
, unsignedOutputs =
mapMaybe (toUnsignedTxOut initialOuts) (decodedTx ^. #outputs)
-- HACK: we leverage that balanceTx will append change outputs after
-- the initial outputs to tell them apart. 'List.\\' does not work
-- when balanceTx may change ada-quantities of initial inputs.
take (length initialOuts)
$ map toUnsignedTxOut (decodedTx ^. #outputs)
, unsignedChange =
mapMaybe (toUnsignedTxChange initialOuts) (decodedTx ^. #outputs)
-- HACK: we leverage that balanceTx will append change outputs after
-- the initial outputs to tell them apart. 'List.\\' does not work
-- when balanceTx may change ada-quantities of initial inputs.
drop (length initialOuts)
$ map toUnsignedTxChange (decodedTx ^. #outputs)
, unsignedWithdrawals =
mapMaybe (toUsignedTxWdrl path) (decodedTx ^. #withdrawals)
}
Expand Down

0 comments on commit 6b1f160

Please sign in to comment.