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
Conversation
There was a problem hiding this 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?
ce11336
to
d958f58
Compare
client/asset/eth/eth.go
Outdated
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposed solution in 6101a6c
d958f58
to
6101a6c
Compare
Pushed two new commits. 0bea901 uses the batched gas limits as a fallback if for some reason reserves are insufficient for the naive 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. |
Will still fail in swap if we did not reserve enough, but it is sure to get an estimate or fail in 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 |
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:
|
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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'soneFee
value.
Oh, @JoeGruffins is doing this in 7222c01. Good.
Before failing to Swap on account of insufficient reserves, use the the realistic gas limit when it is a batch swap.
6101a6c
to
ba8b9fa
Compare
Swapped on mainnet with this rebased on top of the mainnet PR. Branch: https://github.com/chappjc/dcrdex/tree/eth-mainnet%2B%2B |
Closing in favor of #2143 |
Testing a USDC swap, my maker failed (at first) to create the first swap in the sequence with the following error:
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 returnedexecution 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 inredeemGas
).