tokenbridge/monitor/validators.js

187 lines
7.1 KiB
JavaScript
Raw Normal View History

2019-05-08 16:12:02 +03:00
require('dotenv').config()
const Web3Utils = require('web3').utils
2019-05-08 16:12:02 +03:00
const logger = require('./logger')('validators')
2020-11-04 14:24:42 +03:00
const { getBridgeABIs, BRIDGE_VALIDATORS_ABI, gasPriceFromSupplier } = require('../commons')
const { web3Home, web3Foreign, getHomeBlockNumber, getForeignBlockNumber } = require('./utils/web3')
const { getValidatorList } = require('./utils/getValidatorsList')
2019-05-08 16:12:02 +03:00
const {
Consistent variable naming (#198) * Add console.table * First steps in validate script * env rename * Added parameter names * Descriptions * Print and configuration * Added more parameters * Rename gas oracle to gas supplier * More changes * Removed env examples for now * RPC rename * Bridge address rename * More changes * jobs * Renames * Typo * jobs * Changes * jobs * Changes * Monitor changes * jovs * Typo * Changes * REACT_APP_ env prefix * Typo * Rollback changes * Oracle deployment * Defaults * Monitor * Naming * Typo * Typo * Envs * ui deployment * ALl jobs * Vars in ultimate * Lint * Lint * Lint * Another way to add REACT_APP prefixing * Unnecessary mapping * No output timeout * No output timeout * Got rid of ERC20_TOKEN_ADDRESS * Configuration readme * Configuration * Prefixes * timeout * Docs * Docs * docs * docs * docs * Roll back ERC20_TOKEN_ADDRESS for erc-to-erc * Typo * lint * Rollback * ROllback validator * Rollback yarn.lock * dai and wetc update * Rollback ERC20_TOKEN_ADDRESS * erc to native * examples * all jobs * roll back * roll back ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B" * ui env example * typo * Allow rpc for ultimate * Test * ERC20_TOKEN_ADDRESS rollback * Specify port * React port * All jobs * cosmetics * Values * Restore erc20 token * Rearrange example for easier comparision * Rearrange ultimate for easier comparision * Rearrange for easier comparision * Refactor * Conditional app styles * Loading environment variables in react app * Add missing vars for UI in wetc and dai * Bring back test parameters readme * Readme for monitor vars * Reading environment variables in e2e-commons (#207)
2019-09-13 10:11:38 +03:00
COMMON_HOME_BRIDGE_ADDRESS,
COMMON_FOREIGN_BRIDGE_ADDRESS,
COMMON_HOME_GAS_PRICE_SUPPLIER_URL,
COMMON_HOME_GAS_PRICE_SPEED_TYPE,
COMMON_HOME_GAS_PRICE_FALLBACK,
COMMON_HOME_GAS_PRICE_FACTOR,
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL,
COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE,
COMMON_FOREIGN_GAS_PRICE_FALLBACK,
COMMON_FOREIGN_GAS_PRICE_FACTOR,
MONITOR_FOREIGN_VALIDATORS_BALANCE_ENABLE,
MONITOR_HOME_VALIDATORS_BALANCE_ENABLE
2019-05-08 16:12:02 +03:00
} = process.env
const MONITOR_VALIDATOR_HOME_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_HOME_TX_LIMIT) || 0
const MONITOR_VALIDATOR_FOREIGN_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_FOREIGN_TX_LIMIT) || 0
const MONITOR_TX_NUMBER_THRESHOLD = Number(process.env.MONITOR_TX_NUMBER_THRESHOLD) || 100
2019-05-08 16:12:02 +03:00
const homeGasPriceSupplierOpts = {
Consistent variable naming (#198) * Add console.table * First steps in validate script * env rename * Added parameter names * Descriptions * Print and configuration * Added more parameters * Rename gas oracle to gas supplier * More changes * Removed env examples for now * RPC rename * Bridge address rename * More changes * jobs * Renames * Typo * jobs * Changes * jobs * Changes * Monitor changes * jovs * Typo * Changes * REACT_APP_ env prefix * Typo * Rollback changes * Oracle deployment * Defaults * Monitor * Naming * Typo * Typo * Envs * ui deployment * ALl jobs * Vars in ultimate * Lint * Lint * Lint * Another way to add REACT_APP prefixing * Unnecessary mapping * No output timeout * No output timeout * Got rid of ERC20_TOKEN_ADDRESS * Configuration readme * Configuration * Prefixes * timeout * Docs * Docs * docs * docs * docs * Roll back ERC20_TOKEN_ADDRESS for erc-to-erc * Typo * lint * Rollback * ROllback validator * Rollback yarn.lock * dai and wetc update * Rollback ERC20_TOKEN_ADDRESS * erc to native * examples * all jobs * roll back * roll back ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B" * ui env example * typo * Allow rpc for ultimate * Test * ERC20_TOKEN_ADDRESS rollback * Specify port * React port * All jobs * cosmetics * Values * Restore erc20 token * Rearrange example for easier comparision * Rearrange ultimate for easier comparision * Rearrange for easier comparision * Refactor * Conditional app styles * Loading environment variables in react app * Add missing vars for UI in wetc and dai * Bring back test parameters readme * Readme for monitor vars * Reading environment variables in e2e-commons (#207)
2019-09-13 10:11:38 +03:00
speedType: COMMON_HOME_GAS_PRICE_SPEED_TYPE,
factor: COMMON_HOME_GAS_PRICE_FACTOR,
logger
2019-05-08 16:12:02 +03:00
}
const foreignGasPriceSupplierOpts = {
Consistent variable naming (#198) * Add console.table * First steps in validate script * env rename * Added parameter names * Descriptions * Print and configuration * Added more parameters * Rename gas oracle to gas supplier * More changes * Removed env examples for now * RPC rename * Bridge address rename * More changes * jobs * Renames * Typo * jobs * Changes * jobs * Changes * Monitor changes * jovs * Typo * Changes * REACT_APP_ env prefix * Typo * Rollback changes * Oracle deployment * Defaults * Monitor * Naming * Typo * Typo * Envs * ui deployment * ALl jobs * Vars in ultimate * Lint * Lint * Lint * Another way to add REACT_APP prefixing * Unnecessary mapping * No output timeout * No output timeout * Got rid of ERC20_TOKEN_ADDRESS * Configuration readme * Configuration * Prefixes * timeout * Docs * Docs * docs * docs * docs * Roll back ERC20_TOKEN_ADDRESS for erc-to-erc * Typo * lint * Rollback * ROllback validator * Rollback yarn.lock * dai and wetc update * Rollback ERC20_TOKEN_ADDRESS * erc to native * examples * all jobs * roll back * roll back ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B" * ui env example * typo * Allow rpc for ultimate * Test * ERC20_TOKEN_ADDRESS rollback * Specify port * React port * All jobs * cosmetics * Values * Restore erc20 token * Rearrange example for easier comparision * Rearrange ultimate for easier comparision * Rearrange for easier comparision * Refactor * Conditional app styles * Loading environment variables in react app * Add missing vars for UI in wetc and dai * Bring back test parameters readme * Readme for monitor vars * Reading environment variables in e2e-commons (#207)
2019-09-13 10:11:38 +03:00
speedType: COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE,
factor: COMMON_FOREIGN_GAS_PRICE_FACTOR,
logger
}
2019-05-08 16:12:02 +03:00
async function main(bridgeMode) {
2019-05-30 21:05:36 +03:00
const { HOME_ABI, FOREIGN_ABI } = getBridgeABIs(bridgeMode)
Consistent variable naming (#198) * Add console.table * First steps in validate script * env rename * Added parameter names * Descriptions * Print and configuration * Added more parameters * Rename gas oracle to gas supplier * More changes * Removed env examples for now * RPC rename * Bridge address rename * More changes * jobs * Renames * Typo * jobs * Changes * jobs * Changes * Monitor changes * jovs * Typo * Changes * REACT_APP_ env prefix * Typo * Rollback changes * Oracle deployment * Defaults * Monitor * Naming * Typo * Typo * Envs * ui deployment * ALl jobs * Vars in ultimate * Lint * Lint * Lint * Another way to add REACT_APP prefixing * Unnecessary mapping * No output timeout * No output timeout * Got rid of ERC20_TOKEN_ADDRESS * Configuration readme * Configuration * Prefixes * timeout * Docs * Docs * docs * docs * docs * Roll back ERC20_TOKEN_ADDRESS for erc-to-erc * Typo * lint * Rollback * ROllback validator * Rollback yarn.lock * dai and wetc update * Rollback ERC20_TOKEN_ADDRESS * erc to native * examples * all jobs * roll back * roll back ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B" * ui env example * typo * Allow rpc for ultimate * Test * ERC20_TOKEN_ADDRESS rollback * Specify port * React port * All jobs * cosmetics * Values * Restore erc20 token * Rearrange example for easier comparision * Rearrange ultimate for easier comparision * Rearrange for easier comparision * Refactor * Conditional app styles * Loading environment variables in react app * Add missing vars for UI in wetc and dai * Bring back test parameters readme * Readme for monitor vars * Reading environment variables in e2e-commons (#207)
2019-09-13 10:11:38 +03:00
const homeBridge = new web3Home.eth.Contract(HOME_ABI, COMMON_HOME_BRIDGE_ADDRESS)
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
2019-05-30 21:05:36 +03:00
const homeValidatorsAddress = await homeBridge.methods.validatorContract().call()
const homeBridgeValidators = new web3Home.eth.Contract(BRIDGE_VALIDATORS_ABI, homeValidatorsAddress)
2019-05-08 16:12:02 +03:00
2019-05-30 21:05:36 +03:00
logger.debug('getting last block numbers')
2020-11-04 14:24:42 +03:00
const homeBlockNumber = await getHomeBlockNumber()
const foreignBlockNumber = await getForeignBlockNumber()
const homeConfirmations = await homeBridge.methods.requiredBlockConfirmations().call()
const foreignConfirmations = await foreignBridge.methods.requiredBlockConfirmations().call()
const homeDelayedBlockNumber = homeBlockNumber - homeConfirmations
const foreignDelayedBlockNumber = foreignBlockNumber - foreignConfirmations
2019-05-08 16:12:02 +03:00
2019-05-30 21:05:36 +03:00
logger.debug('calling foreignBridge.methods.validatorContract().call()')
const foreignValidatorsAddress = await foreignBridge.methods.validatorContract().call()
const foreignBridgeValidators = new web3Foreign.eth.Contract(BRIDGE_VALIDATORS_ABI, foreignValidatorsAddress)
2019-05-08 16:12:02 +03:00
2019-05-30 21:05:36 +03:00
logger.debug('calling foreignBridgeValidators getValidatorList()')
const foreignValidators = (await getValidatorList(foreignValidatorsAddress, web3Foreign.eth, {
2020-11-04 14:24:42 +03:00
toBlock: foreignBlockNumber,
logger,
chain: 'foreign',
safeToBlock: foreignDelayedBlockNumber
})).map(web3Foreign.utils.toChecksumAddress)
2019-05-08 16:12:02 +03:00
2019-05-30 21:05:36 +03:00
logger.debug('calling homeBridgeValidators getValidatorList()')
const homeValidators = (await getValidatorList(homeValidatorsAddress, web3Home.eth, {
2020-11-04 14:24:42 +03:00
toBlock: homeBlockNumber,
logger,
chain: 'home',
safeToBlock: homeDelayedBlockNumber
})).map(web3Home.utils.toChecksumAddress)
2019-05-08 16:12:02 +03:00
2019-05-30 21:05:36 +03:00
const foreignVBalances = {}
const homeVBalances = {}
let homeGasPrice
let homeGasPriceGwei
let homeTxCost
if (MONITOR_VALIDATOR_HOME_TX_LIMIT) {
logger.debug('calling home getGasPrices')
homeGasPrice =
(await gasPriceFromSupplier(COMMON_HOME_GAS_PRICE_SUPPLIER_URL, homeGasPriceSupplierOpts)) ||
Web3Utils.toBN(COMMON_HOME_GAS_PRICE_FALLBACK)
homeGasPriceGwei = Web3Utils.fromWei(homeGasPrice.toString(), 'gwei')
homeTxCost = homeGasPrice.mul(Web3Utils.toBN(MONITOR_VALIDATOR_HOME_TX_LIMIT))
}
let foreignGasPrice
let foreignGasPriceGwei
let foreignTxCost
if (MONITOR_VALIDATOR_FOREIGN_TX_LIMIT) {
logger.debug('calling foreign getGasPrices')
foreignGasPrice =
(await gasPriceFromSupplier(COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL, foreignGasPriceSupplierOpts)) ||
Web3Utils.toBN(COMMON_FOREIGN_GAS_PRICE_FALLBACK)
foreignGasPriceGwei = Web3Utils.fromWei(foreignGasPrice.toString(), 'gwei')
foreignTxCost = foreignGasPrice.mul(Web3Utils.toBN(MONITOR_VALIDATOR_FOREIGN_TX_LIMIT))
}
2019-05-30 21:05:36 +03:00
let validatorsMatch = true
const foreignValidatorsWithBalanceCheck =
typeof MONITOR_FOREIGN_VALIDATORS_BALANCE_ENABLE === 'string'
? MONITOR_FOREIGN_VALIDATORS_BALANCE_ENABLE.split(' ')
: foreignValidators
logger.debug('getting foreignValidators balances')
await Promise.all(
foreignValidators.map(async v => {
foreignVBalances[v] = {}
if (foreignValidatorsWithBalanceCheck.includes(v)) {
const balance = await web3Foreign.eth.getBalance(v)
foreignVBalances[v].balance = Web3Utils.fromWei(balance)
if (MONITOR_VALIDATOR_FOREIGN_TX_LIMIT) {
foreignVBalances[v].leftTx = Number(
Web3Utils.toBN(balance)
.div(foreignTxCost)
.toString(10)
)
foreignVBalances[v].gasPrice = parseFloat(foreignGasPriceGwei)
}
}
if (!homeValidators.includes(v)) {
validatorsMatch = false
foreignVBalances[v].onlyOnForeign = true
}
})
)
const homeValidatorsWithBalanceCheck =
typeof MONITOR_HOME_VALIDATORS_BALANCE_ENABLE === 'string'
? MONITOR_HOME_VALIDATORS_BALANCE_ENABLE.split(' ')
: homeValidators
logger.debug('calling homeValidators balances')
await Promise.all(
homeValidators.map(async v => {
homeVBalances[v] = {}
if (homeValidatorsWithBalanceCheck.includes(v)) {
const balance = await web3Home.eth.getBalance(v)
homeVBalances[v].balance = Web3Utils.fromWei(balance)
if (MONITOR_VALIDATOR_HOME_TX_LIMIT) {
homeVBalances[v].leftTx = Number(
Web3Utils.toBN(balance)
.div(homeTxCost)
.toString(10)
)
homeVBalances[v].gasPrice = parseFloat(homeGasPriceGwei)
}
}
if (!foreignValidators.includes(v)) {
validatorsMatch = false
homeVBalances[v].onlyOnHome = true
}
})
)
2019-05-30 21:05:36 +03:00
logger.debug('calling homeBridgeValidators.methods.requiredSignatures().call()')
const reqSigHome = await homeBridgeValidators.methods.requiredSignatures().call()
logger.debug('calling foreignBridgeValidators.methods.requiredSignatures().call()')
const reqSigForeign = await foreignBridgeValidators.methods.requiredSignatures().call()
logger.debug('Done')
return {
home: {
validators: homeVBalances,
2019-05-30 21:05:36 +03:00
requiredSignatures: Number(reqSigHome)
},
foreign: {
validators: foreignVBalances,
2019-05-30 21:05:36 +03:00
requiredSignatures: Number(reqSigForeign)
},
requiredSignaturesMatch: reqSigHome === reqSigForeign,
validatorsMatch,
lastChecked: Math.floor(Date.now() / 1000),
homeOk: Object.values(homeVBalances)
.filter(vb => typeof vb.leftTx === 'number')
.every(vb => vb.leftTx >= MONITOR_TX_NUMBER_THRESHOLD),
foreignOk: Object.values(foreignVBalances)
.filter(vb => typeof vb.leftTx === 'number')
.every(vb => vb.leftTx >= MONITOR_TX_NUMBER_THRESHOLD)
2019-05-08 16:12:02 +03:00
}
}
module.exports = main