Add a possibility to fetch gas price from multiple sources (#420)

This commit is contained in:
Kirill Fedoseev 2020-08-23 22:56:59 +03:00 committed by GitHub
parent bea91c0e6e
commit f252ed2618
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 44 additions and 9 deletions

@ -12,7 +12,7 @@ COMMON_HOME_GAS_PRICE_SUPPLIER_URL | The URL used to get a JSON response from th
COMMON_HOME_GAS_PRICE_SPEED_TYPE | Assuming the gas price oracle responds with the following JSON structure: `{"fast": 20.0, "block_time": 12.834, "health": true, "standard": 6.0, "block_number": 6470469, "instant": 71.0, "slow": 1.889}`, this parameter specifies the desirable transaction speed. The speed type can be omitted when `COMMON_HOME_GAS_PRICE_SUPPLIER_URL` is not used. | `instant` / `fast` / `standard` / `slow`
COMMON_HOME_GAS_PRICE_FALLBACK | The gas price (in Wei) that is used if both the oracle and the fall back gas price specified in the Home Bridge contract are not available. | integer
COMMON_HOME_GAS_PRICE_FACTOR | A value that will multiply the gas price of the oracle to convert it to gwei. If the oracle API returns gas prices in gwei then this can be set to `1`. Also, it could be used to intentionally pay more gas than suggested by the oracle to guarantee the transaction verification. E.g. `1.25` or `1.5`. | integer
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL | The URL used to get a JSON response from the gas price prediction oracle for the Foreign network. The provided gas price is used to send the validator's transactions to the RPC node. If the Foreign network is Ethereum Foundation mainnet, the oracle URL can be: https://gasprice.poa.network. Otherwise this parameter can be omitted. | URL
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL | The URL used to get a JSON response from the gas price prediction oracle for the Foreign network. The provided gas price is used to send the validator's transactions to the RPC node. If the Foreign network is Ethereum Foundation mainnet, the oracle URL can be: https://gasprice.poa.network. Otherwise this parameter can be omitted. Set to `gas-price-oracle` if you want to use npm `gas-price-oracle` package for retrieving gas price from multiple sources. | URL
COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE | Assuming the gas price oracle responds with the following JSON structure: `{"fast": 20.0, "block_time": 12.834, "health": true, "standard": 6.0, "block_number": 6470469, "instant": 71.0, "slow": 1.889}`, this parameter specifies the desirable transaction speed. The speed type can be omitted when `COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL`is not used. | `instant` / `fast` / `standard` / `slow`
COMMON_FOREIGN_GAS_PRICE_FALLBACK | The gas price (in Wei) used if both the oracle and fall back gas price specified in the Foreign Bridge contract are not available. | integer
COMMON_FOREIGN_GAS_PRICE_FACTOR | A value that will multiply the gas price of the oracle to convert it to gwei. If the oracle API returns gas prices in gwei then this can be set to `1`. Also, it could be used to intentionally pay more gas than suggested by the oracle to guarantee the transaction verification. E.g. `1.25` or `1.5`. | integer

@ -8,6 +8,7 @@
"test": "NODE_ENV=test mocha"
},
"dependencies": {
"gas-price-oracle": "^0.1.5",
"web3-utils": "1.0.0-beta.34"
},
"devDependencies": {

@ -1,7 +1,10 @@
const { toWei, toBN } = require('web3-utils')
const { GasPriceOracle } = require('gas-price-oracle')
const { BRIDGE_MODES, FEE_MANAGER_MODE, ERC_TYPES } = require('./constants')
const { REWARDABLE_VALIDATORS_ABI } = require('./abis')
const gasPriceOracle = new GasPriceOracle()
function decodeBridgeMode(bridgeModeHash) {
switch (bridgeModeHash) {
case '0x92a8d7fe':
@ -235,8 +238,13 @@ const normalizeGasPrice = (oracleGasPrice, factor, limits = null) => {
// we use built-in 'fetch' on browser side, and `node-fetch` package in Node.
const gasPriceFromSupplier = async (fetchFn, options = {}) => {
try {
let json
if (fetchFn) {
const response = await fetchFn()
const json = await response.json()
json = await response.json()
} else {
json = await gasPriceOracle.fetchGasPricesOffChain()
}
const oracleGasPrice = json[options.speedType]
if (!oracleGasPrice) {

@ -3,4 +3,6 @@ version: '2.4'
services:
monitor:
image: poanetwork/tokenbridge-monitor
build: .
build:
context: ..
dockerfile: ./monitor/Dockerfile

@ -100,8 +100,13 @@ async function main(bridgeMode) {
if (MONITOR_VALIDATOR_FOREIGN_TX_LIMIT) {
logger.debug('calling foreign getGasPrices')
const fetchFn =
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL === 'gas-price-oracle'
? null
: () => fetch(COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL)
foreignGasPrice =
(await gasPriceFromSupplier(() => fetch(COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL), foreignGasPriceSupplierOpts)) ||
(await gasPriceFromSupplier(fetchFn, foreignGasPriceSupplierOpts)) ||
Web3Utils.toBN(COMMON_FOREIGN_GAS_PRICE_FALLBACK)
foreignGasPriceGwei = Web3Utils.fromWei(foreignGasPrice.toString(), 'gwei')
foreignTxCost = foreignGasPrice.mul(Web3Utils.toBN(MONITOR_VALIDATOR_FOREIGN_TX_LIMIT))

@ -3,4 +3,6 @@ version: '2.4'
services:
oracle:
image: poanetwork/tokenbridge-oracle
build: .
build:
context: ..
dockerfile: ./oracle/Dockerfile

@ -73,13 +73,14 @@ async function start(chainId, fetchOnce) {
throw new Error(`Unrecognized chainId '${chainId}'`)
}
const fetchFn = gasPriceSupplierUrl === 'gas-price-oracle' ? null : () => fetch(gasPriceSupplierUrl)
if (fetchOnce) {
await fetchGasPrice(speedType, factor, bridgeContract, () => fetch(gasPriceSupplierUrl))
await fetchGasPrice(speedType, factor, bridgeContract, fetchFn)
return getPrice()
}
fetchGasPriceInterval = setIntervalAndRun(
() => fetchGasPrice(speedType, factor, bridgeContract, () => fetch(gasPriceSupplierUrl)),
() => fetchGasPrice(speedType, factor, bridgeContract, fetchFn),
updateInterval
)
return null

@ -53,7 +53,8 @@ class GasPriceStore {
}
const oracleOptions = { speedType: this.speedType, factor: this.factor, logger: console }
this.gasPrice = (await gasPriceFromSupplier(() => fetch(this.gasPriceSupplierUrl), oracleOptions)) || this.gasPrice
const fetchFn = this.gasPriceSupplierUrl === 'gas-price-oracle' ? null : () => fetch(this.gasPriceSupplierUrl)
this.gasPrice = (await gasPriceFromSupplier(fetchFn, oracleOptions)) || this.gasPrice
setTimeout(() => this.updateGasPrice(), this.updateInterval)
}

@ -4209,6 +4209,13 @@ axios@0.19.0:
follow-redirects "1.5.10"
is-buffer "^2.0.2"
axios@^0.19.2:
version "0.19.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
dependencies:
follow-redirects "1.5.10"
axobject-query@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9"
@ -9822,6 +9829,14 @@ ganache-core@^2.6.0:
ethereumjs-wallet "0.6.3"
web3 "1.2.4"
gas-price-oracle@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/gas-price-oracle/-/gas-price-oracle-0.1.5.tgz#09dd0d9806465c2f5e63b682e6742f96f6eb525c"
integrity sha512-fkaTXnxJcSVco/tMPEcN5gieoUNs8O6JYMXflGLN2+3YeGZAucUI0fgCliazM3nRVAk//bBEm9819/Zb83xhrw==
dependencies:
axios "^0.19.2"
bignumber.js "^9.0.0"
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"