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/asset/eth: don't fail in swapGas on estimateInitGas RPC failure #2118

Closed
wants to merge 4 commits into from

Conversation

chappjc
Copy link
Member

@chappjc chappjc commented Feb 7, 2023

Testing a USDC swap, my maker failed (at first) to create the first swap in the sequence with the following error:

[DBG] CORE: Swappable match 6cdfd20fe1b2bbb168f1c0071ef625d71c1bfc04b4afb6c653a06d02de094788 for order a595439a976bbc4681297efbbbf306e33020fea9e763eec8b90d1ab0137ae2f5 (Maker)
[DBG] CORE: Using stored change coin address: ..., amount:47320000, fees:43560000 (usdc.eth) for order a595439a976bbc4681297efbbbf306e33020fea9e763eec8b90d1ab0137ae2f5 matches
[TRC] CORE[eth][ETH][RPC]: using cached header from "eth-mainnet.blastapi.io"
[ERR] CORE[eth][USDC.ETH]: (60001) error estimating swap gas: execution reverted: transfer from failed
[ERR] CORE: notify: |ERROR| (order) Swap send error - Error encountered sending a swap output(s) worth 47.320000 USDC on order a595439a - Order: a595439a976bbc4681297efbbbf306e33020fea9e763eec8b90d1ab0137ae2f5
[TRC] CORE: notify: |DATA| (balance) balance updated
[ERR] CORE: Route 'match' request handler error (DEX ...): runMatches - {tick of order a595439a976bbc4681297efbbbf306e33020fea9e763eec8b90d1ab0137ae2f5 failed: ... tick: {swapMatches order a595439a976bbc4681297efbbbf306e33020fea9e763eec8b90d1ab0137ae2f5 - {error sending swap transaction: error getting gas fees: execution reverted: transfer from failed}}}

This was not fatal because it retried on the next tick about a minute later, but for some reason it appears that c.cb.EstimateGas for the init tx payload returned execution reverted: transfer from failed. May just be a provider error, but I don't think we need to fail to swap because we can use the known gas cap values (just like we do in redeemGas).

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.

Can you make the log under this 10%% so the 10% prints correctly?

@chappjc chappjc added this to the 0.6 milestone Feb 8, 2023
Comment on lines 1457 to 1460
w.log.Errorf("(%d) error estimating swap gas (using expected gas cap instead): %v", w.assetID, err)
// TODO: investigate "gas required exceeds allowance".
return 0, 0, false, err
// TODO: investigate "error getting gas fees: execution reverted: transfer from failed"
// return 0, 0, false, err
Copy link
Member Author

Choose a reason for hiding this comment

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

I believe whether we fail depends on the caller. FundOrder should probably fail, whilst Swap should not.
This will take some refactoring unfortunately.

Copy link
Member Author

Choose a reason for hiding this comment

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

Proposed solution in 6101a6c

@chappjc chappjc marked this pull request as draft February 9, 2023 15:25
@chappjc
Copy link
Member Author

chappjc commented Feb 9, 2023

Pushed two new commits. 0bea901 uses the batched gas limits as a fallback if for some reason reserves are insufficient for the naive oneSwap * n limit that does not consider batch savings.

6101a6c lets the live estimate remain fatal for order funding and pre-order estimates, but not for the swap when negotiation is already underway.

Need to re-test, but putting back to ready-for-review.

@chappjc chappjc marked this pull request as ready for review February 9, 2023 16:27
@JoeGruffins
Copy link
Member

Will still fail in swap if we did not reserve enough, but it is sure to get an estimate or fail in FundOrder so less likely the second estimate is higher.

What if there was one swap, and the second live estimate was, for whatever reason, one gas higher than the initial. Would that fail?

@chappjc
Copy link
Member Author

chappjc commented Feb 13, 2023

What if there was one swap, and the second live estimate was, for whatever reason, one gas higher than the initial. Would that fail?

Really makes me question the utility of doing a live estimate at swap time (for n=1) at all. This would be an especially frustrating failure mode if the wallet has plenty of available balance and it's just the reserved amts in the funding coins that seem insufficient.

@chappjc
Copy link
Member Author

chappjc commented Feb 13, 2023

Sorry for changing this one so much after your reviews @martonp and @buck54321. #2118 (comment)

The question @JoeGruffins posed remains: if it's a single lot swap (n=1), and order funding got a live estimate of X and used that for reserves, then the live estimate at time of swap got X+1, we'd fail to swap because it exceeds reserves. Options:

  • that's correct, block the swap to avoid a failed transaction
  • Swap anyway with the "third fallback that only uses our known gases" (see code comments, but apply that in the n=1 case too).

oneSwap, _, _, err := w.swapGas(1, swaps.Version)
// Set the gas limit as high as reserves will allow.
n := len(swaps.Contracts)
oneSwap, nSwap, _, err := w.swapGas(n, swaps.Version, false) // allow live est to fail, using our own gas values
Copy link
Contributor

Choose a reason for hiding this comment

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

If the live estimate fails here, and our hardcoded estimates are higher than the actual live estimates, then wouldn't swapVal+fees > reservedVal always be true?

Copy link
Member Author

@chappjc chappjc Feb 14, 2023

Choose a reason for hiding this comment

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

I thought they would be equal. reservedVal should turn out to be swapVal + g.Swap * maxFeeRate * n. Basing that on my understanding on how the reserves (via the fundingCoin) are initially set.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's generally a sign of major problems coming if the live estimates are higher than the hard-coded estimates. In other words, it is (and has been) normal to have the hard coded estimates be what comes out of swapGas.
Consider the code on master, the checks below haven't changed, only added a fallback to the more realistic batched gas limits.

@chappjc
Copy link
Member Author

chappjc commented Feb 14, 2023

I don't think I have the bandwidth to follow through on this swapGas PR, but there are some issues that need to get resolved for 0.6. Maybe these change (or the gist) can be absorbed into #2129?

// TODO: investigate "gas required exceeds allowance".
return 0, 0, false, err
// TODO: investigate "error getting gas fees: execution reverted: transfer from failed" (seems to be approval not actually ready)
Copy link
Member

Choose a reason for hiding this comment

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

Did you see it maybe during MaxOrder or PreSwap? swapGas is used in paths that are called before FundOrder. maybeApproveTokenSwapContract is only called in FundOrder. I think maybe token wallets need to provide requireLiveEst = false in the MaxOrder and PreSwap paths when allowance is required.

Copy link
Member Author

Choose a reason for hiding this comment

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

No, got this from Swap. It was a maker order that was just placed. Taker placed shortly after. Matched and got the error.

Copy link
Member Author

@chappjc chappjc Feb 16, 2023

Choose a reason for hiding this comment

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

Oh, it was also testnet or mainnet, cannot recall. I may have commented on the mainnet eth PR. Almost positive it was the very first trade with the token and it did the approval on the fly when order was created.

I probably had to ignore any preswap error, but again, don't recall.

est.Refund = g.Refund

est.Swap, est.nSwap, _, err = w.swapGas(n, initVer)
est.Swap, est.nSwap, _, err = w.swapGas(n, initVer, true) // fail if live gas estimate fails
Copy link
Member

Choose a reason for hiding this comment

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

While you're here, a few lines down, it says

est.oneGas = est.Swap + est.Redeem
est.nGas = est.nSwap + est.nRedeem

Adding the redeem value there is wrong and pointless. They're both zero. I think those lines needs to come after the redeem wallet check.

Copy link
Member Author

@chappjc chappjc Feb 16, 2023

Choose a reason for hiding this comment

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

Good catch. This would only affect ETH+TOKEN, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Like this? ba8b9fa

I'm now wondering if maxOrder needs to include refund in it's oneFee value.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm now wondering if maxOrder needs to include refund in it's oneFee value.

Oh, @JoeGruffins is doing this in 7222c01. Good.

@chappjc
Copy link
Member Author

chappjc commented Feb 16, 2023

Swapped on mainnet with this rebased on top of the mainnet PR. Branch: https://github.com/chappjc/dcrdex/tree/eth-mainnet%2B%2B
That branch also included @martonp's PR #2125 with 3 providers for the server

@chappjc
Copy link
Member Author

chappjc commented Feb 17, 2023

Closing in favor of #2143

@chappjc chappjc closed this Feb 17, 2023
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.

None yet

4 participants