Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client: fix split option handling #1988

Merged
merged 3 commits into from
Dec 29, 2022
Merged

Conversation

chappjc
Copy link
Member

@chappjc chappjc commented Dec 8, 2022

This fixes a bug in the asset backends' estimateSwap handling when trying a split transaction.

It was possible for the estimates to permit/allow a split even when it would consume more than without a split transaction. The symptom of this was that the "locked" amount estimates obtained when requesting a split could be higher than if not using a split, resulting in an integer underflow in the caller when comparing the two amounts.

Resolves #1959

client/asset: fix estimateSwap split rejection

The enough func in estimateSwap does not account for a split transaction
at the start, so it is possible that funding for trySplit would actually
choose more UTXOs. Actual order funding accounts for this. For this
estimate, we will just not use a split tx if the split-adjusted required
funds exceeds the total value of the UTXO selected with this enough
closure.

The fix is to reject a spit transaction if the output amount plus split tx
fees is less than the sum of the amounts of the utxos selected by fund,
rather than the total of the available utxos provided to fund initially.
There is no point to calling fund again with a different enough func
that accounts for the cost split tx because this indicates it would
reqiure an additional UTXO, thus making the spit txn wasteful.

This also changes how the split order option is emitted from PreSwap so that it is never omitted, instead given a default of false and a reason explaining why it is not effective (wasteful) for the proposed order. This is better than the option not appearing since the UI should be consistent for a given form and wallet. (What happened to the Pre-size option? Sometimes it's just not there.)

client/asset: show split option when ineffectual with reason

image

image


Finally, this also fixes a bug in how core was obtaining PreOrder results for market orders with the spit option enabled. Split transactions are supposed to be disabled/skipped for any order that is immediate (not standing), which includes both market orders and limit orders with immediate time-in-force, as described by the PreSwapForm docs. This fixes how PreSwapForm.Immediate is set by Core so that it is true for market orders as well as immediate limit orders.

client/core: market orders are immediate (PreOrder)


if avail >= reqFunds+extraMaxFees {
reqTotal := reqFunds + splitMaxFees // ~ rather than actually fund()ing again
if reqTotal <= sum {
Copy link
Member Author

@chappjc chappjc Dec 8, 2022

Choose a reason for hiding this comment

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

Comparing against avail instead of sum was the primary bug. If the required amount is more than the amount in the funding coins selected with no split transaction (sum), it is pointless to do a split because it would require another UTXO to be selected just to cover the split tx fees! This is described in the multi-line comment around line 1911.

RealisticBestCase: estLowFees + splitFees,
RealisticWorstCase: estHighFees + splitFees,
}, true, locked, nil
}, true, reqFunds, nil // requires reqTotal, but locks reqFunds in the split output
Copy link
Member Author

@chappjc chappjc Dec 8, 2022

Choose a reason for hiding this comment

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

This was another bug, but not very important. The amount locked by the funding coins for an order funded by a split transaction is precisely the value of the output of the split transaction i.e. reqFunds. The "extra" fees are just burned in making the split transaction, so it's not correct to also call them locked since they are included in the various fee estimates as well.

The tests didn't check for this because we don't test estimateSwap directly, and this locked amount goes nowhere except the text messages in the generated config opt for the UI (reason, etc). The checkSwapEstimate helper had an unused locked arg and I can see why it was unused. I'm not planning to add new tests for this however.

Comment on lines 1868 to 1872
if !splitUsed || splitLocked >= noSplitLocked { // locked check should be redundant
opt.Boolean.Reason = fmt.Sprintf("avoids no %s overlock for this order (ignored)", symbol)
opt.Description = fmt.Sprintf("A split transaction for this order avoids no %s overlock, "+
"but adds additional fees.", symbol)
return opt // do not show by default, but explain why
Copy link
Member Author

Choose a reason for hiding this comment

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

Rather than having a missing option, I believe it is a better UX to show it, unchecked, and with an appropriate reason and description. Otherwise, the user is wondering where the option went that they normally use.

@chappjc chappjc changed the title client/asset: fit split option handling client: fit split option handling Dec 8, 2022
@chappjc chappjc changed the title client: fit split option handling client: fix split option handling Dec 13, 2022
@chappjc chappjc marked this pull request as ready for review December 15, 2022 01:34
@chappjc
Copy link
Member Author

chappjc commented Dec 15, 2022

Not tested as thoroughly as I'd normally do before making ready for review, but it does address the underflow bug.

Copy link
Member

@JoeGruffins JoeGruffins left a comment

Choose a reason for hiding this comment

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

Working well.

The enough func in estimateSwap does not account for a split transaction
at the start, so it is possible that funding for trySplit would actually
choose more UTXOs. Actual order funding accounts for this. For this
estimate, we will just not use a split tx if the split-adjusted required
funds exceeds the total value of the UTXOs selected with this enough
closure.

The fix is to reject a split transaction if the output amount plus
split tx fees is more than the sum of the amounts of the utxos selected
by fund, rather than the total of the available utxos provided to fund
initially. There is no point to calling fund again with a different
enough func that accounts for the cost split tx because this indicates
it would reqiure an additional UTXO, thus making the spit txn wasteful.
@chappjc chappjc added this to the 0.6/1.0 milestone Dec 27, 2022
@chappjc
Copy link
Member Author

chappjc commented Dec 27, 2022

Pls see if you're OK with the conceptual changes to the frontend regarding this order option @buck54321 . Reasoning for not just vanishing the option from the frontend when likely inapplicable: #1988 (comment)

@chappjc chappjc merged commit 92239af into decred:master Dec 29, 2022
@chappjc chappjc deleted the lock-underflow-split branch December 29, 2022 01:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

underflow in overlock savings estimate
3 participants