feat: cached gas prices
This commit is contained in:
parent
e9bfc10588
commit
06b380b488
12
README.md
12
README.md
@ -77,6 +77,8 @@ type GasOracleOptions = {
|
|||||||
defaultRpc?: string
|
defaultRpc?: string
|
||||||
blocksCount?: number
|
blocksCount?: number
|
||||||
percentile?: number
|
percentile?: number
|
||||||
|
blockTime?: number // seconds
|
||||||
|
shouldCache?: boolean
|
||||||
fallbackGasPrices?: FallbackGasPrices
|
fallbackGasPrices?: FallbackGasPrices
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +87,8 @@ const options: GasOracleOptions = {
|
|||||||
percentile: 5, // Which percentile of effective priority fees to include
|
percentile: 5, // Which percentile of effective priority fees to include
|
||||||
blocksCount: 10, // How many blocks to consider for priority fee estimation
|
blocksCount: 10, // How many blocks to consider for priority fee estimation
|
||||||
defaultRpc: 'https://api.mycryptoapi.com/eth',
|
defaultRpc: 'https://api.mycryptoapi.com/eth',
|
||||||
|
blockTime: 10, // seconds
|
||||||
|
shouldCache: false,
|
||||||
timeout: 10000, // specifies the number of milliseconds before the request times out.
|
timeout: 10000, // specifies the number of milliseconds before the request times out.
|
||||||
fallbackGasPrices: {
|
fallbackGasPrices: {
|
||||||
gasPrices: {
|
gasPrices: {
|
||||||
@ -101,6 +105,14 @@ const options: GasOracleOptions = {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### The Oracle can cache rpc calls
|
||||||
|
|
||||||
|
For caching needs to provide to GasOracleOptions
|
||||||
|
|
||||||
|
`shouldCache: true`
|
||||||
|
|
||||||
|
`blockTime: <Chain block time duration>`
|
||||||
|
|
||||||
### EIP-1559 (estimated) gasPrice only
|
### EIP-1559 (estimated) gasPrice only
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gas-price-oracle",
|
"name": "gas-price-oracle",
|
||||||
"version": "0.5.0",
|
"version": "0.5.1",
|
||||||
"description": "Gas Price Oracle library for Ethereum dApps.",
|
"description": "Gas Price Oracle library for Ethereum dApps.",
|
||||||
"homepage": "https://github.com/peppersec/gas-price-oracle",
|
"homepage": "https://github.com/peppersec/gas-price-oracle",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
@ -57,7 +57,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.21.2",
|
"axios": "^0.21.2",
|
||||||
"bignumber.js": "^9.0.0"
|
"bignumber.js": "^9.0.0",
|
||||||
|
"node-cache": "^5.1.2"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib/**/*"
|
"lib/**/*"
|
||||||
|
@ -11,4 +11,17 @@ const INT_PRECISION = 0
|
|||||||
const SUCCESS_STATUS = 200
|
const SUCCESS_STATUS = 200
|
||||||
const BG_ZERO = new BigNumber(0)
|
const BG_ZERO = new BigNumber(0)
|
||||||
const PERCENT_MULTIPLIER = 100
|
const PERCENT_MULTIPLIER = 100
|
||||||
export { GWEI, DEFAULT_TIMEOUT, ROUND_UP, ROUND_DOWN, GWEI_PRECISION, INT_PRECISION, SUCCESS_STATUS, BG_ZERO, PERCENT_MULTIPLIER }
|
const DEFAULT_BLOCK_DURATION = 10
|
||||||
|
|
||||||
|
export {
|
||||||
|
GWEI,
|
||||||
|
DEFAULT_TIMEOUT,
|
||||||
|
ROUND_UP,
|
||||||
|
ROUND_DOWN,
|
||||||
|
GWEI_PRECISION,
|
||||||
|
INT_PRECISION,
|
||||||
|
SUCCESS_STATUS,
|
||||||
|
BG_ZERO,
|
||||||
|
PERCENT_MULTIPLIER,
|
||||||
|
DEFAULT_BLOCK_DURATION,
|
||||||
|
}
|
||||||
|
20
src/services/cacher/cacheNode.ts
Normal file
20
src/services/cacher/cacheNode.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import NodeCache, { Options } from 'node-cache'
|
||||||
|
|
||||||
|
export class NodeJSCache<T> {
|
||||||
|
private nodeCache: NodeCache
|
||||||
|
constructor(params: Options) {
|
||||||
|
this.nodeCache = new NodeCache(params)
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(key: string): Promise<T | undefined> {
|
||||||
|
return await this.nodeCache.get<T>(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
async set(key: string, value: T): Promise<boolean> {
|
||||||
|
return await this.nodeCache.set(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
async has(key: string): Promise<boolean> {
|
||||||
|
return await this.nodeCache.has(key)
|
||||||
|
}
|
||||||
|
}
|
1
src/services/cacher/index.ts
Normal file
1
src/services/cacher/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './cacheNode'
|
@ -3,23 +3,28 @@ import BigNumber from 'bignumber.js'
|
|||||||
import { FeeHistory, Block } from '@/types'
|
import { FeeHistory, Block } from '@/types'
|
||||||
import { Config, EstimateOracle, EstimatedGasPrice, CalculateFeesParams, GasEstimationOptionsPayload } from './types'
|
import { Config, EstimateOracle, EstimatedGasPrice, CalculateFeesParams, GasEstimationOptionsPayload } from './types'
|
||||||
|
|
||||||
import { RpcFetcher } from '@/services'
|
|
||||||
import { ChainId, NETWORKS } from '@/config'
|
import { ChainId, NETWORKS } from '@/config'
|
||||||
import { BG_ZERO, PERCENT_MULTIPLIER } from '@/constants'
|
import { RpcFetcher, NodeJSCache } from '@/services'
|
||||||
import { findMax, fromNumberToHex, fromWeiToGwei, getMedian } from '@/utils'
|
import { findMax, fromNumberToHex, fromWeiToGwei, getMedian } from '@/utils'
|
||||||
|
import { BG_ZERO, DEFAULT_BLOCK_DURATION, PERCENT_MULTIPLIER } from '@/constants'
|
||||||
|
|
||||||
import { DEFAULT_PRIORITY_FEE, PRIORITY_FEE_INCREASE_BOUNDARY, FEE_HISTORY_BLOCKS, FEE_HISTORY_PERCENTILE } from './constants'
|
import { DEFAULT_PRIORITY_FEE, PRIORITY_FEE_INCREASE_BOUNDARY, FEE_HISTORY_BLOCKS, FEE_HISTORY_PERCENTILE } from './constants'
|
||||||
|
|
||||||
// !!! MAKE SENSE ALL CALCULATIONS IN GWEI !!!
|
// !!! MAKE SENSE ALL CALCULATIONS IN GWEI !!!
|
||||||
export class Eip1559GasPriceOracle implements EstimateOracle {
|
export class Eip1559GasPriceOracle implements EstimateOracle {
|
||||||
public configuration: Config = {
|
public configuration: Config = {
|
||||||
|
shouldCache: false,
|
||||||
chainId: ChainId.MAINNET,
|
chainId: ChainId.MAINNET,
|
||||||
|
fallbackGasPrices: undefined,
|
||||||
|
blockTime: DEFAULT_BLOCK_DURATION,
|
||||||
blocksCount: NETWORKS[ChainId.MAINNET].blocksCount,
|
blocksCount: NETWORKS[ChainId.MAINNET].blocksCount,
|
||||||
percentile: NETWORKS[ChainId.MAINNET].percentile,
|
percentile: NETWORKS[ChainId.MAINNET].percentile,
|
||||||
fallbackGasPrices: undefined,
|
|
||||||
}
|
}
|
||||||
private fetcher: RpcFetcher
|
private fetcher: RpcFetcher
|
||||||
|
|
||||||
|
private cache: NodeJSCache<EstimatedGasPrice>
|
||||||
|
private FEES_KEY = (chainId: ChainId) => `estimate-fee-${chainId}`
|
||||||
|
|
||||||
constructor({ fetcher, ...options }: GasEstimationOptionsPayload) {
|
constructor({ fetcher, ...options }: GasEstimationOptionsPayload) {
|
||||||
this.fetcher = fetcher
|
this.fetcher = fetcher
|
||||||
const chainId = options?.chainId || this.configuration.chainId
|
const chainId = options?.chainId || this.configuration.chainId
|
||||||
@ -29,10 +34,19 @@ export class Eip1559GasPriceOracle implements EstimateOracle {
|
|||||||
if (options) {
|
if (options) {
|
||||||
this.configuration = { ...this.configuration, ...options }
|
this.configuration = { ...this.configuration, ...options }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.cache = new NodeJSCache({ stdTTL: this.configuration.blockTime, useClones: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
public async estimateFees(fallbackGasPrices?: EstimatedGasPrice): Promise<EstimatedGasPrice> {
|
public async estimateFees(fallbackGasPrices?: EstimatedGasPrice): Promise<EstimatedGasPrice> {
|
||||||
try {
|
try {
|
||||||
|
const cacheKey = this.FEES_KEY(this.configuration.chainId)
|
||||||
|
const cachedFees = await this.cache.get(cacheKey)
|
||||||
|
|
||||||
|
if (cachedFees) {
|
||||||
|
return cachedFees
|
||||||
|
}
|
||||||
|
|
||||||
const { data: latestBlock } = await this.fetcher.makeRpcCall<{ result: Block }>({
|
const { data: latestBlock } = await this.fetcher.makeRpcCall<{ result: Block }>({
|
||||||
method: 'eth_getBlockByNumber',
|
method: 'eth_getBlockByNumber',
|
||||||
params: ['latest', false],
|
params: ['latest', false],
|
||||||
@ -52,7 +66,12 @@ export class Eip1559GasPriceOracle implements EstimateOracle {
|
|||||||
params: [blockCount, 'latest', rewardPercentiles],
|
params: [blockCount, 'latest', rewardPercentiles],
|
||||||
})
|
})
|
||||||
|
|
||||||
return this.calculateFees({ baseFee, feeHistory: data.result })
|
const fees = await this.calculateFees({ baseFee, feeHistory: data.result })
|
||||||
|
if (this.configuration.shouldCache) {
|
||||||
|
await this.cache.set(cacheKey, fees)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fees
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (fallbackGasPrices) {
|
if (fallbackGasPrices) {
|
||||||
return fallbackGasPrices
|
return fallbackGasPrices
|
||||||
|
@ -23,6 +23,8 @@ export type Options = {
|
|||||||
chainId?: number
|
chainId?: number
|
||||||
blocksCount?: number
|
blocksCount?: number
|
||||||
percentile?: number
|
percentile?: number
|
||||||
|
blockTime?: number
|
||||||
|
shouldCache?: boolean
|
||||||
fallbackGasPrices: EstimatedGasPrice | undefined
|
fallbackGasPrices: EstimatedGasPrice | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ export type GasOracleOptions = {
|
|||||||
defaultRpc?: string
|
defaultRpc?: string
|
||||||
blocksCount?: number
|
blocksCount?: number
|
||||||
percentile?: number
|
percentile?: number
|
||||||
|
blockTime?: number
|
||||||
|
shouldCache?: boolean
|
||||||
fallbackGasPrices?: FallbackGasPrices
|
fallbackGasPrices?: FallbackGasPrices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,4 +3,5 @@ export * from './gas-price-oracle'
|
|||||||
export * from './gas-estimation'
|
export * from './gas-estimation'
|
||||||
export * from './legacy-gas-price'
|
export * from './legacy-gas-price'
|
||||||
|
|
||||||
|
export * from './cacher'
|
||||||
export * from './rpcFetcher'
|
export * from './rpcFetcher'
|
||||||
|
@ -14,9 +14,9 @@ import {
|
|||||||
GetGasPriceFromRespInput,
|
GetGasPriceFromRespInput,
|
||||||
} from './types'
|
} from './types'
|
||||||
|
|
||||||
import { RpcFetcher } from '@/services'
|
|
||||||
import { ChainId, NETWORKS } from '@/config'
|
import { ChainId, NETWORKS } from '@/config'
|
||||||
import { GWEI, DEFAULT_TIMEOUT, GWEI_PRECISION } from '@/constants'
|
import { RpcFetcher, NodeJSCache } from '@/services'
|
||||||
|
import { GWEI, DEFAULT_TIMEOUT, GWEI_PRECISION, DEFAULT_BLOCK_DURATION } from '@/constants'
|
||||||
|
|
||||||
import { MULTIPLIERS, DEFAULT_GAS_PRICE } from './constants'
|
import { MULTIPLIERS, DEFAULT_GAS_PRICE } from './constants'
|
||||||
|
|
||||||
@ -95,22 +95,27 @@ export class LegacyGasPriceOracle implements LegacyOracle {
|
|||||||
public onChainOracles: OnChainOracles = {}
|
public onChainOracles: OnChainOracles = {}
|
||||||
public offChainOracles: OffChainOracles = {}
|
public offChainOracles: OffChainOracles = {}
|
||||||
public configuration: Required<LegacyOptions> = {
|
public configuration: Required<LegacyOptions> = {
|
||||||
|
shouldCache: false,
|
||||||
chainId: ChainId.MAINNET,
|
chainId: ChainId.MAINNET,
|
||||||
timeout: DEFAULT_TIMEOUT,
|
timeout: DEFAULT_TIMEOUT,
|
||||||
|
blockTime: DEFAULT_BLOCK_DURATION,
|
||||||
defaultRpc: NETWORKS[ChainId.MAINNET].rpcUrl,
|
defaultRpc: NETWORKS[ChainId.MAINNET].rpcUrl,
|
||||||
fallbackGasPrices: LegacyGasPriceOracle.getMultipliedPrices(NETWORKS[ChainId.MAINNET].defaultGasPrice),
|
fallbackGasPrices: LegacyGasPriceOracle.getMultipliedPrices(NETWORKS[ChainId.MAINNET].defaultGasPrice),
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly fetcher: RpcFetcher
|
private readonly fetcher: RpcFetcher
|
||||||
|
|
||||||
|
private cache: NodeJSCache<GasPrice>
|
||||||
|
private LEGACY_KEY = (chainId: ChainId) => `legacy-fee-${chainId}`
|
||||||
|
|
||||||
constructor({ fetcher, ...options }: LegacyOptionsPayload) {
|
constructor({ fetcher, ...options }: LegacyOptionsPayload) {
|
||||||
this.fetcher = fetcher
|
this.fetcher = fetcher
|
||||||
if (options) {
|
if (options) {
|
||||||
this.configuration = { ...this.configuration, ...options }
|
this.configuration = { ...this.configuration, ...options }
|
||||||
}
|
}
|
||||||
|
|
||||||
const fallbackGasPrices =
|
const { defaultGasPrice } = NETWORKS[ChainId.MAINNET]
|
||||||
this.configuration.fallbackGasPrices || LegacyGasPriceOracle.getMultipliedPrices(NETWORKS[ChainId.MAINNET].defaultGasPrice)
|
const fallbackGasPrices = this.configuration.fallbackGasPrices || LegacyGasPriceOracle.getMultipliedPrices(defaultGasPrice)
|
||||||
this.configuration.fallbackGasPrices = LegacyGasPriceOracle.normalize(fallbackGasPrices)
|
this.configuration.fallbackGasPrices = LegacyGasPriceOracle.normalize(fallbackGasPrices)
|
||||||
|
|
||||||
const network = NETWORKS[this.configuration.chainId]?.oracles
|
const network = NETWORKS[this.configuration.chainId]?.oracles
|
||||||
@ -118,6 +123,8 @@ export class LegacyGasPriceOracle implements LegacyOracle {
|
|||||||
this.offChainOracles = { ...network.offChainOracles }
|
this.offChainOracles = { ...network.offChainOracles }
|
||||||
this.onChainOracles = { ...network.onChainOracles }
|
this.onChainOracles = { ...network.onChainOracles }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.cache = new NodeJSCache({ stdTTL: this.configuration.blockTime, useClones: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
public addOffChainOracle(oracle: OffChainOracle): void {
|
public addOffChainOracle(oracle: OffChainOracle): void {
|
||||||
@ -228,9 +235,19 @@ export class LegacyGasPriceOracle implements LegacyOracle {
|
|||||||
this.lastGasPrice = fallbackGasPrices || this.configuration.fallbackGasPrices
|
this.lastGasPrice = fallbackGasPrices || this.configuration.fallbackGasPrices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cacheKey = this.LEGACY_KEY(this.configuration.chainId)
|
||||||
|
const cachedFees = await this.cache.get(cacheKey)
|
||||||
|
|
||||||
|
if (cachedFees) {
|
||||||
|
return cachedFees
|
||||||
|
}
|
||||||
|
|
||||||
if (Object.keys(this.offChainOracles).length > 0) {
|
if (Object.keys(this.offChainOracles).length > 0) {
|
||||||
try {
|
try {
|
||||||
this.lastGasPrice = await this.fetchGasPricesOffChain(shouldGetMedian)
|
this.lastGasPrice = await this.fetchGasPricesOffChain(shouldGetMedian)
|
||||||
|
if (this.configuration.shouldCache) {
|
||||||
|
await this.cache.set(cacheKey, this.lastGasPrice)
|
||||||
|
}
|
||||||
return this.lastGasPrice
|
return this.lastGasPrice
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to fetch gas prices from offchain oracles...')
|
console.error('Failed to fetch gas prices from offchain oracles...')
|
||||||
@ -240,7 +257,11 @@ export class LegacyGasPriceOracle implements LegacyOracle {
|
|||||||
if (Object.keys(this.onChainOracles).length > 0) {
|
if (Object.keys(this.onChainOracles).length > 0) {
|
||||||
try {
|
try {
|
||||||
const fastGas = await this.fetchGasPricesOnChain()
|
const fastGas = await this.fetchGasPricesOnChain()
|
||||||
|
|
||||||
this.lastGasPrice = LegacyGasPriceOracle.getCategorize(fastGas)
|
this.lastGasPrice = LegacyGasPriceOracle.getCategorize(fastGas)
|
||||||
|
if (this.configuration.shouldCache) {
|
||||||
|
await this.cache.set(cacheKey, this.lastGasPrice)
|
||||||
|
}
|
||||||
return this.lastGasPrice
|
return this.lastGasPrice
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to fetch gas prices from onchain oracles...')
|
console.error('Failed to fetch gas prices from onchain oracles...')
|
||||||
@ -249,7 +270,11 @@ export class LegacyGasPriceOracle implements LegacyOracle {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const fastGas = await this.fetchGasPriceFromRpc()
|
const fastGas = await this.fetchGasPriceFromRpc()
|
||||||
|
|
||||||
this.lastGasPrice = LegacyGasPriceOracle.getCategorize(fastGas)
|
this.lastGasPrice = LegacyGasPriceOracle.getCategorize(fastGas)
|
||||||
|
if (this.configuration.shouldCache) {
|
||||||
|
await this.cache.set(cacheKey, this.lastGasPrice)
|
||||||
|
}
|
||||||
return this.lastGasPrice
|
return this.lastGasPrice
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to fetch gas prices from default RPC. Last known gas will be returned')
|
console.error('Failed to fetch gas prices from default RPC. Last known gas will be returned')
|
||||||
|
@ -36,7 +36,9 @@ export type GasPrice = Record<GasPriceKey, number>
|
|||||||
export type LegacyOptions = {
|
export type LegacyOptions = {
|
||||||
chainId?: number
|
chainId?: number
|
||||||
timeout?: number
|
timeout?: number
|
||||||
|
blockTime?: number
|
||||||
defaultRpc?: string
|
defaultRpc?: string
|
||||||
|
shouldCache?: boolean
|
||||||
fallbackGasPrices?: GasPrice
|
fallbackGasPrices?: GasPrice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import chaiAsPromised from 'chai-as-promised'
|
|||||||
import mockery from 'mockery'
|
import mockery from 'mockery'
|
||||||
import { before, describe } from 'mocha'
|
import { before, describe } from 'mocha'
|
||||||
|
|
||||||
|
import { sleep } from '@/utils'
|
||||||
import { ChainId, NETWORKS } from '@/config'
|
import { ChainId, NETWORKS } from '@/config'
|
||||||
import { GWEI_PRECISION } from '@/constants'
|
import { GWEI_PRECISION } from '@/constants'
|
||||||
|
|
||||||
@ -122,6 +123,24 @@ describe('eip-1559 gasOracle', function () {
|
|||||||
estimateGas.maxFeePerGas.should.be.at.equal(estimatedMaxFee)
|
estimateGas.maxFeePerGas.should.be.at.equal(estimatedMaxFee)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
it('should cache', async function () {
|
||||||
|
eipOracle = new GasPriceOracle({ shouldCache: true, chainId })
|
||||||
|
const estimateGasFirst: EstimatedGasPrice = await eipOracle.eip1559.estimateFees()
|
||||||
|
|
||||||
|
await sleep(2000)
|
||||||
|
const estimateGasSecond: EstimatedGasPrice = await eipOracle.eip1559.estimateFees()
|
||||||
|
|
||||||
|
if (estimateGasFirst?.maxFeePerGas) {
|
||||||
|
estimateGasFirst.maxFeePerGas.should.be.at.equal(estimateGasSecond?.maxFeePerGas)
|
||||||
|
}
|
||||||
|
|
||||||
|
await sleep(4000)
|
||||||
|
const estimateGasThird: EstimatedGasPrice = await eipOracle.eip1559.estimateFees()
|
||||||
|
|
||||||
|
if (estimateGasSecond?.maxFeePerGas) {
|
||||||
|
estimateGasSecond.maxFeePerGas.should.be.at.equal(estimateGasThird?.maxFeePerGas)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -8,6 +8,7 @@ import mockery from 'mockery'
|
|||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import { before, describe } from 'mocha'
|
import { before, describe } from 'mocha'
|
||||||
|
|
||||||
|
import { sleep } from '@/utils'
|
||||||
import { ChainId, NETWORKS } from '@/config'
|
import { ChainId, NETWORKS } from '@/config'
|
||||||
import { DEFAULT_TIMEOUT } from '@/constants'
|
import { DEFAULT_TIMEOUT } from '@/constants'
|
||||||
import { GasPriceOracle } from '@/services/gas-price-oracle'
|
import { GasPriceOracle } from '@/services/gas-price-oracle'
|
||||||
@ -77,6 +78,7 @@ describe('legacy gasOracle', function () {
|
|||||||
mockery.enable({ useCleanCache: true, warnOnUnregistered: false })
|
mockery.enable({ useCleanCache: true, warnOnUnregistered: false })
|
||||||
const { GasPriceOracle } = require('../index')
|
const { GasPriceOracle } = require('../index')
|
||||||
oracle = new GasPriceOracle()
|
oracle = new GasPriceOracle()
|
||||||
|
// @ts-ignore
|
||||||
await oracle.legacy.fetchGasPricesOffChain(true).should.be.rejectedWith('All oracles are down. Probably a network error.')
|
await oracle.legacy.fetchGasPricesOffChain(true).should.be.rejectedWith('All oracles are down. Probably a network error.')
|
||||||
mockery.disable()
|
mockery.disable()
|
||||||
})
|
})
|
||||||
@ -105,6 +107,7 @@ describe('legacy gasOracle', function () {
|
|||||||
it('should remove oracle', async function () {
|
it('should remove oracle', async function () {
|
||||||
await oracle.legacy.fetchGasPricesOnChain()
|
await oracle.legacy.fetchGasPricesOnChain()
|
||||||
oracle.legacy.removeOnChainOracle('chainlink')
|
oracle.legacy.removeOnChainOracle('chainlink')
|
||||||
|
// @ts-ignore
|
||||||
await oracle.legacy.fetchGasPricesOnChain().should.be.rejectedWith('All oracles are down. Probably a network error.')
|
await oracle.legacy.fetchGasPricesOnChain().should.be.rejectedWith('All oracles are down. Probably a network error.')
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -113,6 +116,7 @@ describe('legacy gasOracle', function () {
|
|||||||
await oracle.legacy.fetchGasPricesOnChain()
|
await oracle.legacy.fetchGasPricesOnChain()
|
||||||
oracle.legacy.removeOnChainOracle('chainlink')
|
oracle.legacy.removeOnChainOracle('chainlink')
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
await oracle.legacy.fetchGasPricesOnChain().should.be.rejectedWith('All oracles are down. Probably a network error.')
|
await oracle.legacy.fetchGasPricesOnChain().should.be.rejectedWith('All oracles are down. Probably a network error.')
|
||||||
|
|
||||||
oracle.legacy.addOnChainOracle(toAdd)
|
oracle.legacy.addOnChainOracle(toAdd)
|
||||||
@ -127,6 +131,7 @@ describe('legacy gasOracle', function () {
|
|||||||
const { GasPriceOracle } = require('../index')
|
const { GasPriceOracle } = require('../index')
|
||||||
|
|
||||||
oracle = new GasPriceOracle()
|
oracle = new GasPriceOracle()
|
||||||
|
// @ts-ignore
|
||||||
await oracle.legacy.fetchGasPricesOnChain().should.be.rejectedWith('All oracles are down. Probably a network error.')
|
await oracle.legacy.fetchGasPricesOnChain().should.be.rejectedWith('All oracles are down. Probably a network error.')
|
||||||
mockery.disable()
|
mockery.disable()
|
||||||
})
|
})
|
||||||
@ -157,6 +162,7 @@ describe('legacy gasOracle', function () {
|
|||||||
const { GasPriceOracle } = require('../index')
|
const { GasPriceOracle } = require('../index')
|
||||||
|
|
||||||
oracle = new GasPriceOracle()
|
oracle = new GasPriceOracle()
|
||||||
|
// @ts-ignore
|
||||||
await oracle.legacy.fetchGasPriceFromRpc().should.be.rejectedWith('Default RPC is down. Probably a network error.')
|
await oracle.legacy.fetchGasPriceFromRpc().should.be.rejectedWith('Default RPC is down. Probably a network error.')
|
||||||
mockery.disable()
|
mockery.disable()
|
||||||
})
|
})
|
||||||
@ -217,6 +223,25 @@ describe('legacy gasOracle', function () {
|
|||||||
|
|
||||||
mockery.disable()
|
mockery.disable()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should cache', async function () {
|
||||||
|
const oracle = new GasPriceOracle({ shouldCache: true })
|
||||||
|
const gasPricesFirst = await oracle.legacy.gasPrices()
|
||||||
|
|
||||||
|
await sleep(2000)
|
||||||
|
const gasPricesSecond = await oracle.legacy.gasPrices()
|
||||||
|
|
||||||
|
if (gasPricesFirst.fast) {
|
||||||
|
gasPricesFirst.fast.should.be.at.equal(gasPricesSecond?.fast)
|
||||||
|
}
|
||||||
|
|
||||||
|
await sleep(4000)
|
||||||
|
const gasPricesThird = await oracle.legacy.gasPrices()
|
||||||
|
|
||||||
|
if (gasPricesSecond.fast) {
|
||||||
|
gasPricesSecond.fast.should.be.at.equal(gasPricesThird?.fast)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('median', function () {
|
describe('median', function () {
|
||||||
|
@ -1,2 +1,8 @@
|
|||||||
export * from './math'
|
export * from './math'
|
||||||
export * from './crypto'
|
export * from './crypto'
|
||||||
|
|
||||||
|
const sleep = (time: number): Promise<boolean> => {
|
||||||
|
return new Promise((res) => setTimeout(() => res(true), time))
|
||||||
|
}
|
||||||
|
|
||||||
|
export { sleep }
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -467,6 +467,11 @@ cliui@^5.0.0:
|
|||||||
strip-ansi "^5.2.0"
|
strip-ansi "^5.2.0"
|
||||||
wrap-ansi "^5.1.0"
|
wrap-ansi "^5.1.0"
|
||||||
|
|
||||||
|
clone@2.x:
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
|
||||||
|
integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==
|
||||||
|
|
||||||
color-convert@^1.9.0:
|
color-convert@^1.9.0:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||||
@ -1520,6 +1525,13 @@ natural-compare@^1.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||||
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
||||||
|
|
||||||
|
node-cache@^5.1.2:
|
||||||
|
version "5.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-5.1.2.tgz#f264dc2ccad0a780e76253a694e9fd0ed19c398d"
|
||||||
|
integrity sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==
|
||||||
|
dependencies:
|
||||||
|
clone "2.x"
|
||||||
|
|
||||||
node-environment-flags@1.0.6:
|
node-environment-flags@1.0.6:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088"
|
resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088"
|
||||||
|
Loading…
Reference in New Issue
Block a user