From fab22ee05feff86abf2d3c7a9ca3bb0ced64893d Mon Sep 17 00:00:00 2001 From: Niranjana Binoy <43930900+NiranjanaBinoy@users.noreply.github.com> Date: Thu, 18 Feb 2021 21:48:23 -0500 Subject: [PATCH] Fetch eth_gasprice in send flow on non-Mainnet networks (#10444) --- ui/app/ducks/gas/gas-duck.test.js | 47 +++++++++++++++++++++++ ui/app/ducks/gas/gas.duck.js | 59 ++++++++++++++++++++++++----- ui/app/pages/send/send.component.js | 1 + 3 files changed, 98 insertions(+), 9 deletions(-) diff --git a/ui/app/ducks/gas/gas-duck.test.js b/ui/app/ducks/gas/gas-duck.test.js index 4e7be7956..b1c8447d9 100644 --- a/ui/app/ducks/gas/gas-duck.test.js +++ b/ui/app/ducks/gas/gas-duck.test.js @@ -2,6 +2,7 @@ import assert from 'assert'; import nock from 'nock'; import sinon from 'sinon'; import proxyquire from 'proxyquire'; +import BN from 'bn.js'; const fakeStorage = {}; @@ -58,6 +59,16 @@ describe('Gas Duck', function () { basicEstimateIsLoading: true, basicPriceEstimatesLastRetrieved: 0, }; + + const providerState = { + chainId: '0x1', + nickname: '', + rpcPrefs: {}, + rpcUrl: '', + ticker: 'ETH', + type: 'mainnet', + }; + const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'; const BASIC_GAS_ESTIMATE_LOADING_STARTED = @@ -165,6 +176,7 @@ describe('Gas Duck', function () { await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState, basicPriceAEstimatesLastRetrieved: 1000000 }, + metamask: { provider: { ...providerState } }, })); assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, @@ -193,6 +205,39 @@ describe('Gas Duck', function () { ]); }); + it('should call fetch with the expected params for test network', async function () { + global.eth = { gasPrice: sinon.fake.returns(new BN(48199313, 10)) }; + + const mockDistpatch = sinon.spy(); + const providerStateForTestNetwrok = { + chainId: '0x5', + nickname: '', + rpcPrefs: {}, + rpcUrl: '', + ticker: 'ETH', + type: 'goerli', + }; + + await fetchBasicGasEstimates()(mockDistpatch, () => ({ + gas: { ...initState, basicPriceAEstimatesLastRetrieved: 1000000 }, + metamask: { provider: { ...providerStateForTestNetwrok } }, + })); + assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ + { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, + ]); + assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ + { + type: SET_BASIC_GAS_ESTIMATE_DATA, + value: { + average: 0.0482, + }, + }, + ]); + assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ + { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, + ]); + }); + it('should fetch recently retrieved estimates from storage', async function () { const mockDistpatch = sinon.spy(); @@ -209,6 +254,7 @@ describe('Gas Duck', function () { await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState }, + metamask: { provider: { ...providerState } }, })); assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, @@ -244,6 +290,7 @@ describe('Gas Duck', function () { await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState }, + metamask: { provider: { ...providerState } }, })); assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, diff --git a/ui/app/ducks/gas/gas.duck.js b/ui/app/ducks/gas/gas.duck.js index 73a621f8f..d97dd70c4 100644 --- a/ui/app/ducks/gas/gas.duck.js +++ b/ui/app/ducks/gas/gas.duck.js @@ -1,8 +1,12 @@ import { cloneDeep } from 'lodash'; import BigNumber from 'bignumber.js'; import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers'; -import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util'; +import { + decGWEIToHexWEI, + getValueFromWeiHex, +} from '../../helpers/utils/conversions.util'; import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'; +import { getIsMainnet, getCurrentChainId } from '../../selectors'; const fetchWithTimeout = getFetchWithTimeout(30000); @@ -111,7 +115,9 @@ async function basicGasPriceQuery() { export function fetchBasicGasEstimates() { return async (dispatch, getState) => { + const isMainnet = getIsMainnet(getState()); const { basicPriceEstimatesLastRetrieved } = getState().gas; + const timeLastRetrieved = basicPriceEstimatesLastRetrieved || (await getStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED')) || @@ -120,15 +126,19 @@ export function fetchBasicGasEstimates() { dispatch(basicGasEstimatesLoadingStarted()); let basicEstimates; - if (Date.now() - timeLastRetrieved > 75000) { - basicEstimates = await fetchExternalBasicGasEstimates(dispatch); + if (isMainnet || process.env.IN_TEST) { + if (Date.now() - timeLastRetrieved > 75000) { + basicEstimates = await fetchExternalBasicGasEstimates(dispatch); + } else { + const cachedBasicEstimates = await getStorageItem( + 'BASIC_PRICE_ESTIMATES', + ); + basicEstimates = + cachedBasicEstimates || + (await fetchExternalBasicGasEstimates(dispatch)); + } } else { - const cachedBasicEstimates = await getStorageItem( - 'BASIC_PRICE_ESTIMATES', - ); - basicEstimates = - cachedBasicEstimates || - (await fetchExternalBasicGasEstimates(dispatch)); + basicEstimates = await fetchEthGasPriceEstimates(getState()); } dispatch(setBasicGasEstimateData(basicEstimates)); @@ -161,6 +171,37 @@ async function fetchExternalBasicGasEstimates(dispatch) { setStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', timeRetrieved), ]); dispatch(setBasicPriceEstimatesLastRetrieved(timeRetrieved)); + return basicEstimates; +} + +async function fetchEthGasPriceEstimates(state) { + const chainId = getCurrentChainId(state); + const [cachedTimeLastRetrieved, cachedBasicEstimates] = await Promise.all([ + getStorageItem(`${chainId}_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED`), + getStorageItem(`${chainId}_BASIC_PRICE_ESTIMATES`), + ]); + const timeLastRetrieved = cachedTimeLastRetrieved || 0; + if (cachedBasicEstimates && Date.now() - timeLastRetrieved < 75000) { + return cachedBasicEstimates; + } + const gasPrice = await global.eth.gasPrice(); + const averageGasPriceInDecGWEI = getValueFromWeiHex({ + value: gasPrice.toString(16), + numberOfDecimals: 4, + toDenomination: 'GWEI', + }); + const basicEstimates = { + average: Number(averageGasPriceInDecGWEI), + }; + const timeRetrieved = Date.now(); + + await Promise.all([ + setStorageItem(`${chainId}_BASIC_PRICE_ESTIMATES`, basicEstimates), + setStorageItem( + `${chainId}_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED`, + timeRetrieved, + ), + ]); return basicEstimates; } diff --git a/ui/app/pages/send/send.component.js b/ui/app/pages/send/send.component.js index 74d4f86f4..3fbd7ecd8 100644 --- a/ui/app/pages/send/send.component.js +++ b/ui/app/pages/send/send.component.js @@ -147,6 +147,7 @@ export default class SendTransactionScreen extends Component { address, }); updateToNicknameIfNecessary(to, toNickname, addressBook); + this.props.fetchBasicGasEstimates(); updateGas = true; } }