From d866a721de2155d74e3eb3ed37765b226058cf54 Mon Sep 17 00:00:00 2001 From: Kieran Allen <132384348+kallen-ledger@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:53:16 +0000 Subject: [PATCH] [feat/LIVE-8381]: add 10s timeout on estimate gas calls for (#4987) * feat: add 10s timeout on estimate gas calls for * chore: add changeset * feat: add comment and num formatting * feat: add unit test --- .changeset/silver-lamps-warn.md | 9 +++++++++ apps/ledger-live-desktop/static/i18n/en/app.json | 3 +++ .../src/locales/en/common.json | 3 +++ .../__tests__/unit/api/node/ledger.unit.test.ts | 16 ++++++++++++++++ libs/coin-evm/src/api/node/ledger.ts | 6 ++++-- .../exchange/swap/hooks/useSwapTransaction.ts | 15 +++++++++++++-- libs/ledgerjs/packages/errors/src/index.ts | 1 + 7 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 .changeset/silver-lamps-warn.md diff --git a/.changeset/silver-lamps-warn.md b/.changeset/silver-lamps-warn.md new file mode 100644 index 000000000000..5322fba1a3cd --- /dev/null +++ b/.changeset/silver-lamps-warn.md @@ -0,0 +1,9 @@ +--- +"@ledgerhq/errors": patch +"ledger-live-desktop": patch +"live-mobile": patch +"@ledgerhq/live-common": patch +"@ledgerhq/coin-evm": patch +--- + +add 10s timeout to estimate gas diff --git a/apps/ledger-live-desktop/static/i18n/en/app.json b/apps/ledger-live-desktop/static/i18n/en/app.json index e8889844eaf5..e4dc3770f42e 100644 --- a/apps/ledger-live-desktop/static/i18n/en/app.json +++ b/apps/ledger-live-desktop/static/i18n/en/app.json @@ -5457,6 +5457,9 @@ "FeeNotLoaded": { "title": "Couldn't load fee rates. Please set manual fees" }, + "FeeNotLoadedSwap": { + "title": "Network fee estimation failed because of technical issues. Try again or change the assets." + }, "FeeRequired": { "title": "Fees are required" }, diff --git a/apps/ledger-live-mobile/src/locales/en/common.json b/apps/ledger-live-mobile/src/locales/en/common.json index eb5e5431dae3..9321c5a4f94b 100644 --- a/apps/ledger-live-mobile/src/locales/en/common.json +++ b/apps/ledger-live-mobile/src/locales/en/common.json @@ -313,6 +313,9 @@ "FeeNotLoaded": { "title": "Could not load fee rates" }, + "FeeNotLoadedSwap": { + "title": "Network fee estimation failed because of technical issues. Try again or change the assets." + }, "FeeRequired": { "title": "Fees are required" }, diff --git a/libs/coin-evm/src/__tests__/unit/api/node/ledger.unit.test.ts b/libs/coin-evm/src/__tests__/unit/api/node/ledger.unit.test.ts index 52b392078286..3cd0cea1bb1d 100644 --- a/libs/coin-evm/src/__tests__/unit/api/node/ledger.unit.test.ts +++ b/libs/coin-evm/src/__tests__/unit/api/node/ledger.unit.test.ts @@ -275,6 +275,22 @@ describe("EVM Family", () => { } }); + it("should throw GasEstimationError if request throws ECONNABORTED", async () => { + jest + .spyOn(axios, "request") + .mockImplementation(() => Promise.reject({ code: "ECONNABORTED" })); + + try { + await LEDGER_API.getGasEstimation(account, {} as any); + fail("Promise should have been rejected"); + } catch (e) { + if (e instanceof AssertionError) { + throw e; + } + expect(e).toBeInstanceOf(GasEstimationError); + } + }); + it("should return the expected payload", async () => { jest.spyOn(axios, "request").mockImplementation(async ({ data: transaction }) => { return (transaction as any)?.data?.length > 2 diff --git a/libs/coin-evm/src/api/node/ledger.ts b/libs/coin-evm/src/api/node/ledger.ts index 36a550b33a10..83f895a853ec 100644 --- a/libs/coin-evm/src/api/node/ledger.ts +++ b/libs/coin-evm/src/api/node/ledger.ts @@ -15,7 +15,8 @@ import { NodeApi, isLedgerNodeConfig } from "./types"; import { getGasOptions } from "../gasTracker/ledger"; import { padHexString } from "../../logic"; -export const LEDGER_TIMEOUT = 200; // 200ms between 2 calls +export const LEDGER_TIMEOUT = 10_000; // 10_000ms (10s) for network call timeout +export const LEDGER_TIME_BETWEEN_TRIES = 200; // 200ms between 2 calls export const DEFAULT_RETRIES_API = 2; export async function fetchWithRetries( @@ -35,7 +36,7 @@ export async function fetchWithRetries( } catch (e) { if (retries) { // wait the API timeout before trying again - await delay(LEDGER_TIMEOUT); + await delay(LEDGER_TIME_BETWEEN_TRIES); // decrement with prefix here or it won't work return fetchWithRetries(params, --retries); } @@ -185,6 +186,7 @@ export const getGasEstimation: NodeApi["getGasEstimation"] = async ( estimated_gas_limit: string; }>({ method: "POST", + timeout: LEDGER_TIMEOUT, url: `${getEnv("EXPLORER")}/blockchain/v4/${node.explorerId}/tx/estimate-gas-limit`, data: { from: account.freshAddress, // should be necessary for some estimations diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts b/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts index 5305976ce04b..0152039b01b9 100644 --- a/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts +++ b/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts @@ -1,4 +1,10 @@ -import { AmountRequired, NotEnoughGas, NotEnoughGasSwap } from "@ledgerhq/errors"; +import { + AmountRequired, + FeeNotLoaded, + FeeNotLoadedSwap, + NotEnoughGas, + NotEnoughGasSwap, +} from "@ledgerhq/errors"; import { useMemo } from "react"; import { SwapSelectorStateType, @@ -73,6 +79,11 @@ export const useFromAmountStatusMessage = ( }); } + // convert to swap variation of error to display correct message to frontend. + if (relevantStatus instanceof FeeNotLoaded) { + return new FeeNotLoadedSwap(); + } + return relevantStatus; }, [statusEntries, currency, estimatedFees, transaction?.amount, account?.id, parentAccount?.id]); }; @@ -122,7 +133,7 @@ export const useSwapTransaction = ({ const { account: toAccount } = toState; - const fromAmountError = useFromAmountStatusMessage(bridgeTransaction, ["amount"]); + const fromAmountError = useFromAmountStatusMessage(bridgeTransaction, ["amount", "gasLimit"]); // treat the gasPrice error as a warning for swap. const fromAmountWarning = useFromAmountStatusMessage(bridgeTransaction, ["gasPrice"]); diff --git a/libs/ledgerjs/packages/errors/src/index.ts b/libs/ledgerjs/packages/errors/src/index.ts index bd7aea298cea..db9455b766e2 100644 --- a/libs/ledgerjs/packages/errors/src/index.ts +++ b/libs/ledgerjs/packages/errors/src/index.ts @@ -140,6 +140,7 @@ export const WrongAppForCurrency = createCustomErrorClass("WrongAppForCurrency") export const ETHAddressNonEIP = createCustomErrorClass("ETHAddressNonEIP"); export const CantScanQRCode = createCustomErrorClass("CantScanQRCode"); export const FeeNotLoaded = createCustomErrorClass("FeeNotLoaded"); +export const FeeNotLoadedSwap = createCustomErrorClass("FeeNotLoadedSwap"); export const FeeRequired = createCustomErrorClass("FeeRequired"); export const FeeTooHigh = createCustomErrorClass("FeeTooHigh"); export const PendingOperation = createCustomErrorClass("PendingOperation");