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

swap: stuck due to low fee (potential solutions) #3135

Open
norwnd opened this issue Jan 2, 2025 · 4 comments
Open

swap: stuck due to low fee (potential solutions) #3135

norwnd opened this issue Jan 2, 2025 · 4 comments

Comments

@norwnd
Copy link
Contributor

norwnd commented Jan 2, 2025

It is possible for Swap transaction to get stuck for 8+ hours (and/or never get mined),

I'm not sure what happens in case such Swap transaction does get mined eventually - I'm assuming Bison wallet will realize it needs to refund it ASAP and will send a Refund transaction (for Maker that's safe behavior, for Taker that's safe until 20h into the Match),

but what happens in case such Swap transaction never gets mined is - corresponding Match ends up in a hanging state where "it thinks Swap happened" (even thought it actually didn't) and "it thinks Refund is coming" (even though Bison wallet cannot possibly refund it since there is nothing to refund); all the while wallet also thinks Swap transaction is pending in mempool (which is technically correct but might be confusing to a User, so it's probably best to clean it up after Match state is resolved one way or another), here is how such stuck Match looks like:

image

I think there are at least two different ways this can be addressed:

  1. (optimistic) just do nothing until certain timestamp in the future, and then simply clean-up Match and wallet Swap transaction pending in mempool; that's simple but could be naive in case Swap transaction does get mined eventually against all the odds
  2. (proper) or instead issue a so-called Cancel transaction spending Swap funding coin forcefully to make sure Swap transaction never comes back to life guaranteed (perhaps only after network fees have dropped and are reasonably low)

Another note, #3131 also probably depends on the resolution of this issue since Swapping balance (under Locked section) keeps showing funds reserved by stuck Swap transaction even after I've sent another Polygon transaction with the same nonce that got mined (effectively replacing/invalidating that Swap transaction completely) - which is probably due to corresponding Match still expecting Refund that will never happen.

Another aspect of this issue - it seems bumping fee for Swap transaction for EVM-based assets (through manual user-action request) isn't working correctly because if Swap tx1 was replaced by tx2 (with higher fee) Match won't know about it and we keep trying to convince server tx1 is the Swap transaction to look for (we do refund Swap tx2 successfully in that case though, that's good 👍 )

it seems Redeems/Refunds would suffer from exactly the same issue of Match being unaware of fee-bumped transaction - but the code handle this for Redeems/Refunds exists (see code around ConfirmTransaction in https://github.com/decred/dcrdex/pull/3082/files) ... and that probably means we need

  • to have similar functionality for Swaps
  • it's a bit unfortunate that for EVM-based transactions to bump fees "manual user action" is required (while for BTC or DCR it's handled automatically), perhaps it would be best to automate this for EVM-based assets as well ("manual user action" would need to be disabled for every transaction type except for Sends I guess to prevent interference with automated fee-bump functionality) - this is especially desirable for Swap transactions where user simply might not have enough time to react if he doesn't monitor all his open trades 24/7
@JoeGruffins
Copy link
Member

I'm not sure atm why we don't automatically increase evm tx fees.

The philosophy behind not watching the swap initiation tx so much is that it's not usually a threat of losing funds. Plus it happens now so it's unlikely that, if we have tx fee info now, it isn't mined. In a few hours whenever we might need to send the next tx we expect fee to be unknown.

Perhaps you are right though and we should monitor swap tx. Just monitor all the things.

@JoeGruffins
Copy link
Member

I want to add an AbandonTx method to the client/asset/Wallet interface and just abandon the swap tx inside of Refund/ConfirmRefund in the event that the swap isn't mined yet. I think that's the easiest way to resolve this issue.

Maybe we should also monitor init but I don't know since it usually isn't a problem (afaik). @buck54321 what do you think?

@buck54321
Copy link
Member

I think these are all good ideas, but each one opens a can of worms. Automatically spending more than we have reserved is super-problematic, especially so for bots. I'll put some more thought into this and we can touch base again next week. Or feel free to bring it up on Matrix too.

@norwnd
Copy link
Contributor Author

norwnd commented Jan 17, 2025

Automatically spending more than we have reserved is super-problematic, especially so for bots.

I see what you mean with respect to fee reserves - if wallet spends all its funds/reserves on initiating a bunch of Swaps there might not be enough left to Redeem/Refund to finish corresponding trades,

I think one solution would be to hard-limit how many matches an order can have. This would allow to solve 2 issues:

  • this one (related to spending more than we reserved)
  • and also drastically decrease the required amount of funds to lock to cover fees to even being able to place a trade (which I've complained about on Matrix a while ago, still thinking that requiring POL holdings on the order of ~1% of the trade is ~100x higher than what I would consider reasonable)

So, lets say we limit matches per order at 16 (I don't see a strong reason for it to be much higher). Client would simply keep track of this and refuse to initiate 17th match and beyond. And Server would also need to permit revocation for an order that has reached its limit (perhaps it should issue server-side revocation in that case, I guess that mirrors existing "revocation due to client inactivity" mechanism nicely).

As for fee reserves, we lock funds that cover 16 * WorstFeePerMatch taking into account all possible fee-bumps (Swap+Refund and Redeem depending on which side we are - Maker/Taker). The only problem is it would be simpler to put a hard number on WorstFeePerMatch if Client could rely on some sort of fee-rate limit imposed by his wallet (in wallet settings) which in current master version is mostly ignored (perhaps consulted against in some cases but certainly not respected in most) - that's another issue which I've left some thoughts on here but even without the exact fee-rate limit a simple heuristic to estimate WorstFeePerMatch can be used (10x the current fee-rate or something).

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

No branches or pull requests

5 participants
@buck54321 @JoeGruffins @norwnd and others