Skip to content
This repository was archived by the owner on Dec 2, 2024. It is now read-only.

Add AdjustUnbalancedTx effect #419

Merged
6 commits merged into from
Jun 1, 2022
Merged

Add AdjustUnbalancedTx effect #419

6 commits merged into from
Jun 1, 2022

Conversation

ghost
Copy link

@ghost ghost commented Apr 14, 2022

Adds AdjustUnbalancedTx PABReq effect that uses protocol parameters.

Should fix #414.


Pre-submit checklist:

  • Branch
    • Tests are provided (if possible)
    • Commit sequence broadly makes sense
    • Key commits have useful messages
    • Relevant tickets are mentioned in commit messages
    • Formatting, materialized Nix files, PNG optimization, etc. are updated
  • PR
    • Self-reviewed the diff
    • Useful pull request description
    • Reviewer requested

@ghost ghost force-pushed the contract-adjust-unbalanced branch from f5e3d45 to 261eff0 Compare April 19, 2022 11:37
@ghost ghost requested review from sjoerdvisscher and koslambrou April 19, 2022 11:37
@ghost ghost marked this pull request as ready for review April 19, 2022 11:37
@sjoerdvisscher
Copy link
Contributor

coinsPerUTxOWord is not a drop-in replacement for minAdaTxOut. See https://github.com/input-output-hk/cardano-ledger/blob/master/doc/explanations/min-utxo-alonzo.rst for details. I'm still not sure what the best way is to fix #414.

@ghost
Copy link
Author

ghost commented Apr 19, 2022

@sjoerdvisscher hmm, well, there are

I suppose we should use it but I suspect we don't already do it because we need to convert the transaction from our representation to the cardano-node's types?

@sjoerdvisscher
Copy link
Contributor

sjoerdvisscher commented Apr 19, 2022

We even have Ledger.Validation.evaluateMinLovelaceOutput and Ledger.Validation.fromPlutusTxOut which together can easily calculate the correct amount. (In fact, evaluateMinLovelaceOutput should use fromPlutusTxOut) But we suspect it will be really hard to fix all the testcases. But maybe you want to try it out?

@ghost ghost force-pushed the contract-adjust-unbalanced branch from 2b94ec1 to a44e654 Compare April 20, 2022 14:15
@ghost ghost requested a review from koslambrou April 22, 2022 10:42
@sjoerdvisscher
Copy link
Contributor

@ak3n What's the status of this?

@ghost
Copy link
Author

ghost commented May 9, 2022

@sjoerdvisscher I had to switch to a different task. Will get back to this PR a bit later.

@ghost ghost force-pushed the contract-adjust-unbalanced branch from 07327d3 to 9e99391 Compare May 10, 2022 16:20
@sjoerdvisscher sjoerdvisscher mentioned this pull request May 18, 2022
8 tasks
@ghost ghost force-pushed the contract-adjust-unbalanced branch from 56c39ca to a9532b3 Compare May 20, 2022 14:33
@ghost ghost requested a review from koslambrou May 20, 2022 14:51
(Left _, _) -> (acc, txOut) -- acc is an error, do nothing
(Right _, Left e) -> (Left e, txOut) -- failed somewhere, return error as acc
(Right acc', Right (ada, txOut')) -> (Right $ ada:acc', txOut')
adjustTxOut :: TxOut -> Either Tx.ToCardanoError (Ada.Ada, TxOut)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you let this return Either Tx.ToCardanoError ([Ada.Ada], TxOut) you have 2 nested applicative effects (Either Tx.ToCardanoError and (,) [Ada.Ada]), which you could use in a traversal using Compose. Then you won't need step.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please elaborate or provide an example how to do it? I thought how to compose traversal and fold here (we want to traverse UnbalancedTx and also collect some info at the same time) but ended up with step solution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This worked even better than I thought, trying it out in vscode I got:

adjustUnbalancedTx params = alaf Compose (tx . Tx.outputs . traverse) adjustTxOut

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, indeed, looks cool and works fine! Thanks!

But lacks some readability as non-trivial lens code as usual.

_ -> []
otherWalletsTxOutCosts = concatMap (map Ada.fromValue . snd) $ txOutCosts
let txOutCosts' = concatMap snd $ filter ((== w) . fst) txOutCosts
otherWalletsTxOutCosts = concatMap snd txOutCosts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this allWalletsTxOutCosts?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, indeed, thanks for pointing this out. I will refactor and write a comment a bit later.

@ghost ghost force-pushed the contract-adjust-unbalanced branch from 54cd01d to d7b31b7 Compare May 24, 2022 14:49
@ghost ghost requested review from sjoerdvisscher and koslambrou May 25, 2022 09:32
@ghost ghost force-pushed the contract-adjust-unbalanced branch from 6ec19e2 to 7200032 Compare May 25, 2022 17:02
@ghost ghost requested a review from sjoerdvisscher May 25, 2022 17:03
import PlutusTx.Prelude qualified as P
import Wallet.Emulator (Wallet)

-- | Returns the calculated delta between initial and final values. Might be false positive.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "false positive"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a risk when expected delta has only ada part and expected delta /= realDelta and realDelta is divisible by some delta from deltas, then we will return realDelta's ada. Which means that the test will pass but without strong confidence in wallets' funds consistency.

For example, we expected -n, but there is n among deltas and realDelta is n, it is divisible by n => our test will pass.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this explanation should be added as a comment on the function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to the comment. 👍

@ghost ghost requested a review from koslambrou May 26, 2022 07:03
@sjoerdvisscher
Copy link
Contributor

Looking at what the problem could be with

walletsAdjustedTxEvents = preMapMaybe (preview (eteEvent . walletEvent' . to (\x -> (x ^. _1, x ^. _2 . _RequestHandlerLog . _AdjustingUnbalancedTx)))) L.list

One thing I notice is _2 is a lens and _RequestHandlerLog . _AdjustingUnbalancedTx) is a prism, so composed they make a traversal. When applied to ^. a traversal needs a monoid instance on the result, which is [Ada.ada] here. So one difference with walletAdjustedTxEvents w is that for each wallet event that does't match _RequestHandlerLog . _AdjustingUnbalancedTx you get a result with an empty list. I still don't see how this could cause missing data though.

I do think that with the current implementation you don't need the wallet in the return value, since you throw them away in allWalletsTxOutCosts, so a safer implementation could be

walletsAdjustedTxEvents = preMapMaybe (preview (eteEvent . walletEvent' . _2 . _RequestHandlerLog . _AdjustingUnbalancedTx)) L.list

@ghost ghost force-pushed the contract-adjust-unbalanced branch from c6a6969 to a105b34 Compare May 31, 2022 10:07
@ghost
Copy link
Author

ghost commented May 31, 2022

@sjoerdvisscher

Thanks, it works. I remember that initially I tried to go this way but later decided to add the information about wallets trying to be more precise with deltas using the the wallet against other wallet strategy instead of all wallets against all wallets because it might generate more unnecessary deltas and increase the risk of false positive results.

@sjoerdvisscher
Copy link
Contributor

sjoerdvisscher commented May 31, 2022

Well you could still do that (I think) by passing the result of Folds.walletAdjustedTxEvents w directly to calculateDelta. I can't really judge if that's worth it.

@koslambrou
Copy link
Contributor

@ak3n You can merge whenever you think it's done :)

@ghost ghost merged commit 2d09427 into main Jun 1, 2022
@ghost ghost deleted the contract-adjust-unbalanced branch June 1, 2022 09:28
koslambrou pushed a commit that referenced this pull request Jun 22, 2022
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Contract Model failing to validate with UtxoFailure OutputTooSmallUTxO
3 participants