Skip to content

Commit

Permalink
fix: eth_feeHistory by passing 'latest' block number, meanwhile prese…
Browse files Browse the repository at this point in the history
…rving the researcher's ability to quote against past number including gas fees (Uniswap#459)

* fix eth_feeHistory by passing 'latest' block number, meanwhile preserving the researcher's ability to quote against past number including gas fees

* fix requestBlockNumber pass into eth_feeHistory RPC format

* address feedbacks, remove unnecessary log info
  • Loading branch information
jsy1218 authored Dec 18, 2023
1 parent 71fac19 commit 2bac562
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 26 deletions.
12 changes: 7 additions & 5 deletions src/providers/caching-gas-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ export class CachingGasStationProvider extends IGasPriceProvider {
super();
}

public override async getGasPrice(requestBlockNumber: number): Promise<GasPrice> {
const cachedGasPrice = await this.cache.get(this.GAS_KEY(this.chainId, requestBlockNumber));
public override async getGasPrice(latestBlockNumber: number, requestBlockNumber?: number): Promise<GasPrice> {
// If block number is specified in the request, we have to use that block number find any potential cache hits.
// Otherwise, we can use the latest block number.
const targetBlockNumber = requestBlockNumber ?? latestBlockNumber;
const cachedGasPrice = await this.cache.get(this.GAS_KEY(this.chainId, targetBlockNumber));

if (cachedGasPrice) {
log.info(
Expand All @@ -40,9 +43,8 @@ export class CachingGasStationProvider extends IGasPriceProvider {
return cachedGasPrice;
}

log.info('Gas station price local cache miss.');
const gasPrice = await this.gasPriceProvider.getGasPrice(requestBlockNumber);
await this.cache.set(this.GAS_KEY(this.chainId, requestBlockNumber), gasPrice);
const gasPrice = await this.gasPriceProvider.getGasPrice(latestBlockNumber, requestBlockNumber);
await this.cache.set(this.GAS_KEY(this.chainId, targetBlockNumber), gasPrice);

return gasPrice;
}
Expand Down
7 changes: 5 additions & 2 deletions src/providers/eip-1559-gas-price-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,17 @@ export class EIP1559GasPriceProvider extends IGasPriceProvider {
super();
}

public override async getGasPrice(requestBlockNumber: number): Promise<GasPrice> {
public override async getGasPrice(_latestBlockNumber: number, requestBlockNumber?: number): Promise<GasPrice> {
const feeHistoryRaw = (await this.provider.send('eth_feeHistory', [
/**
* @fix Use BigNumber.from(this.blocksToConsider).toHexString() after hardhat adds support
* @see https://github.com/NomicFoundation/hardhat/issues/1585 .___.
*/
BigNumber.from(this.blocksToConsider).toHexString().replace('0x0', '0x'),
BigNumber.from(requestBlockNumber).toHexString().replace('0x0', '0x'),
// If the block number is not specified, we have to send hardcoded 'latest' to infura RPC
// because Infura node pool is eventually consistent and may not have the latest block from our block number.
// See https://uniswapteam.slack.com/archives/C023A7JDTJP/p1702485038251449?thread_ts=1702471203.519869&cid=C023A7JDTJP
requestBlockNumber ? BigNumber.from(requestBlockNumber).toHexString().replace('0x0', '0x') : 'latest',
[this.priorityFeePercentile],
])) as RawFeeHistoryResponse;

Expand Down
3 changes: 1 addition & 2 deletions src/providers/eth-gas-station-info-gas-price-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ export class ETHGasStationInfoProvider extends IGasPriceProvider {
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public override async getGasPrice(_requestBlockNumber: number): Promise<GasPrice> {
log.info(`About to get gas prices from gas station ${this.url}`);
public override async getGasPrice(_latestBlockNumber: number, _requestBlockNumber?: number): Promise<GasPrice> {
const response = await retry(
async () => {
return axios.get<ETHGasStationResponse>(this.url);
Expand Down
2 changes: 1 addition & 1 deletion src/providers/gas-price-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export type GasPrice = {
* Provider for getting gas prices.
*/
export abstract class IGasPriceProvider {
public abstract getGasPrice(requestBlockNumber: number): Promise<GasPrice>;
public abstract getGasPrice(latestBlockNumber: number, requestBlockNumber?: number): Promise<GasPrice>;
}
9 changes: 1 addition & 8 deletions src/providers/legacy-gas-price-provider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { JsonRpcProvider } from '@ethersproject/providers';

import { log } from '../util';

import { GasPrice, IGasPriceProvider } from './gas-price-provider';

export class LegacyGasPriceProvider extends IGasPriceProvider {
Expand All @@ -10,13 +8,8 @@ export class LegacyGasPriceProvider extends IGasPriceProvider {
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public override async getGasPrice(_requestBlockNumber: number): Promise<GasPrice> {
public override async getGasPrice(_latestBlockNumber: number, _requestBlockNumber?: number): Promise<GasPrice> {
const gasPriceWei = await this.provider.getGasPrice();
log.info(
{ gasPriceWei },
`Got gas price ${gasPriceWei} using eth_gasPrice RPC`
);

return {
gasPriceWei,
};
Expand Down
6 changes: 3 additions & 3 deletions src/providers/on-chain-gas-price-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ export class OnChainGasPriceProvider extends IGasPriceProvider {
super();
}

public override async getGasPrice(requestBlockNumber: number): Promise<GasPrice> {
public override async getGasPrice(latestBlockNumber: number, requestBlockNumber?: number): Promise<GasPrice> {
if (this.eipChains.includes(this.chainId)) {
return this.eip1559GasPriceProvider.getGasPrice(requestBlockNumber);
return this.eip1559GasPriceProvider.getGasPrice(latestBlockNumber, requestBlockNumber);
}

return this.legacyGasPriceProvider.getGasPrice(requestBlockNumber);
return this.legacyGasPriceProvider.getGasPrice(latestBlockNumber, requestBlockNumber);
}
}
2 changes: 1 addition & 1 deletion src/providers/static-gas-price-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { GasPrice, IGasPriceProvider } from './gas-price-provider';
export class StaticGasPriceProvider implements IGasPriceProvider {
constructor(private gasPriceWei: BigNumber) {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async getGasPrice(_requestBlockNumber: number): Promise<GasPrice> {
async getGasPrice(_latestBlockNumber: number, _requestBlockNumber?: number): Promise<GasPrice> {
return { gasPriceWei: this.gasPriceWei };
}
}
8 changes: 7 additions & 1 deletion src/providers/tenderly-simulation-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,13 @@ export class TenderlySimulator extends Simulator {
url,
body,
opts
);
).finally(() => {
metric.putMetric(
'TenderlySimulationLatencies',
Date.now() - before,
MetricLoggerUnit.Milliseconds
);
});

const latencies = Date.now() - before;
log.info(
Expand Down
6 changes: 3 additions & 3 deletions src/routers/alpha-router/alpha-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,7 @@ export class AlphaRouter
log.warn(`Finalized routing config is ${JSON.stringify(routingConfig)}`);
}

const gasPriceWei = await this.getGasPriceWei(await blockNumber);
const gasPriceWei = await this.getGasPriceWei(await blockNumber, await partialRoutingConfig.blockNumber);

const quoteToken = quoteCurrency.wrapped;
const providerConfig: ProviderConfig = {
Expand Down Expand Up @@ -1948,12 +1948,12 @@ export class AlphaRouter
}
}

private async getGasPriceWei(blockNumber: number): Promise<BigNumber> {
private async getGasPriceWei(latestBlockNumber: number, requestBlockNumber?: number): Promise<BigNumber> {
// Track how long it takes to resolve this async call.
const beforeGasTimestamp = Date.now();

// Get an estimate of the gas price to use when estimating gas cost of different routes.
const { gasPriceWei } = await this.gasPriceProvider.getGasPrice(blockNumber);
const { gasPriceWei } = await this.gasPriceProvider.getGasPrice(latestBlockNumber, requestBlockNumber);

metric.putMetric(
'GasPriceLoad',
Expand Down

0 comments on commit 2bac562

Please sign in to comment.