2019-05-08 16:12:02 +03:00
|
|
|
require('dotenv').config()
|
|
|
|
const Web3 = require('web3')
|
|
|
|
const fetch = require('node-fetch')
|
|
|
|
const logger = require('./logger')('validators')
|
2019-09-13 15:54:51 +03:00
|
|
|
const { getBridgeABIs, BRIDGE_VALIDATORS_ABI, getValidatorList, gasPriceFromSupplier } = require('../commons')
|
2019-05-08 16:12:02 +03:00
|
|
|
const { getBlockNumber } = require('./utils/contract')
|
|
|
|
|
|
|
|
const {
|
2019-09-13 10:11:38 +03:00
|
|
|
COMMON_HOME_RPC_URL,
|
|
|
|
COMMON_FOREIGN_RPC_URL,
|
|
|
|
COMMON_HOME_BRIDGE_ADDRESS,
|
|
|
|
COMMON_FOREIGN_BRIDGE_ADDRESS,
|
|
|
|
MONITOR_VALIDATOR_HOME_TX_LIMIT,
|
|
|
|
COMMON_HOME_GAS_PRICE_SUPPLIER_URL,
|
|
|
|
COMMON_HOME_GAS_PRICE_SPEED_TYPE,
|
|
|
|
COMMON_HOME_GAS_PRICE_FALLBACK,
|
|
|
|
COMMON_HOME_GAS_PRICE_FACTOR,
|
|
|
|
MONITOR_VALIDATOR_FOREIGN_TX_LIMIT,
|
|
|
|
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL,
|
|
|
|
COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE,
|
|
|
|
COMMON_FOREIGN_GAS_PRICE_FALLBACK,
|
|
|
|
COMMON_FOREIGN_GAS_PRICE_FACTOR
|
2019-05-08 16:12:02 +03:00
|
|
|
} = process.env
|
2019-09-13 10:11:38 +03:00
|
|
|
const MONITOR_HOME_START_BLOCK = Number(process.env.MONITOR_HOME_START_BLOCK) || 0
|
|
|
|
const MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
|
2019-05-08 16:12:02 +03:00
|
|
|
|
|
|
|
const Web3Utils = Web3.utils
|
|
|
|
|
2019-09-13 10:11:38 +03:00
|
|
|
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
2019-05-08 16:12:02 +03:00
|
|
|
const web3Home = new Web3(homeProvider)
|
|
|
|
|
2019-09-13 10:11:38 +03:00
|
|
|
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
2019-05-08 16:12:02 +03:00
|
|
|
const web3Foreign = new Web3(foreignProvider)
|
|
|
|
|
2019-09-13 15:54:51 +03:00
|
|
|
const homeGasPriceSupplierOpts = {
|
2019-09-13 10:11:38 +03:00
|
|
|
speedType: COMMON_HOME_GAS_PRICE_SPEED_TYPE,
|
|
|
|
factor: COMMON_HOME_GAS_PRICE_FACTOR,
|
2019-08-05 18:22:57 +03:00
|
|
|
logger
|
2019-05-08 16:12:02 +03:00
|
|
|
}
|
|
|
|
|
2019-09-13 15:54:51 +03:00
|
|
|
const foreignGasPriceSupplierOpts = {
|
2019-09-13 10:11:38 +03:00
|
|
|
speedType: COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE,
|
|
|
|
factor: COMMON_FOREIGN_GAS_PRICE_FACTOR,
|
2019-08-05 18:22:57 +03:00
|
|
|
logger
|
2019-07-12 19:10:17 +03:00
|
|
|
}
|
|
|
|
|
2019-08-05 18:22:57 +03:00
|
|
|
const asyncForEach = async (array, callback) => {
|
|
|
|
for (let index = 0; index < array.length; index++) {
|
|
|
|
await callback(array[index], index, array)
|
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)
|
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()
|
2019-08-01 16:10:22 +03:00
|
|
|
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')
|
|
|
|
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
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()
|
2019-08-01 16:10:22 +03:00
|
|
|
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()')
|
2019-08-08 16:27:09 +03:00
|
|
|
const foreignValidators = await getValidatorList(foreignValidatorsAddress, web3Foreign.eth, {
|
2019-09-13 10:11:38 +03:00
|
|
|
from: MONITOR_FOREIGN_START_BLOCK,
|
2019-08-08 16:27:09 +03:00
|
|
|
to: foreignBlockNumber,
|
|
|
|
logger
|
|
|
|
})
|
2019-05-08 16:12:02 +03:00
|
|
|
|
2019-05-30 21:05:36 +03:00
|
|
|
logger.debug('calling homeBridgeValidators getValidatorList()')
|
2019-08-08 16:27:09 +03:00
|
|
|
const homeValidators = await getValidatorList(homeValidatorsAddress, web3Home.eth, {
|
2019-09-13 10:11:38 +03:00
|
|
|
from: MONITOR_HOME_START_BLOCK,
|
2019-08-08 16:27:09 +03:00
|
|
|
to: homeBlockNumber,
|
|
|
|
logger
|
|
|
|
})
|
2019-05-08 16:12:02 +03:00
|
|
|
|
2019-05-30 21:05:36 +03:00
|
|
|
const homeBalances = {}
|
|
|
|
logger.debug('calling asyncForEach homeValidators homeBalances')
|
|
|
|
await asyncForEach(homeValidators, async v => {
|
|
|
|
homeBalances[v] = Web3Utils.fromWei(await web3Home.eth.getBalance(v))
|
|
|
|
})
|
|
|
|
const foreignVBalances = {}
|
|
|
|
const homeVBalances = {}
|
2019-07-12 19:10:17 +03:00
|
|
|
|
|
|
|
logger.debug('calling home getGasPrices')
|
2019-08-05 18:22:57 +03:00
|
|
|
const homeGasPrice =
|
2019-09-13 15:54:51 +03:00
|
|
|
(await gasPriceFromSupplier(() => fetch(COMMON_HOME_GAS_PRICE_SUPPLIER_URL), homeGasPriceSupplierOpts)) ||
|
2019-09-13 10:11:38 +03:00
|
|
|
Web3Utils.toBN(COMMON_HOME_GAS_PRICE_FALLBACK)
|
2019-07-12 19:10:17 +03:00
|
|
|
const homeGasPriceGwei = Web3Utils.fromWei(homeGasPrice.toString(), 'gwei')
|
2019-09-13 10:11:38 +03:00
|
|
|
const homeTxCost = homeGasPrice.mul(Web3Utils.toBN(MONITOR_VALIDATOR_HOME_TX_LIMIT))
|
2019-07-12 19:10:17 +03:00
|
|
|
|
|
|
|
logger.debug('calling foreign getGasPrices')
|
2019-08-05 18:22:57 +03:00
|
|
|
const foreignGasPrice =
|
2019-09-13 15:54:51 +03:00
|
|
|
(await gasPriceFromSupplier(() => fetch(COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL), foreignGasPriceSupplierOpts)) ||
|
2019-09-13 10:11:38 +03:00
|
|
|
Web3Utils.toBN(COMMON_FOREIGN_GAS_PRICE_FALLBACK)
|
2019-07-12 19:10:17 +03:00
|
|
|
const foreignGasPriceGwei = Web3Utils.fromWei(foreignGasPrice.toString(), 'gwei')
|
2019-09-13 10:11:38 +03:00
|
|
|
const foreignTxCost = foreignGasPrice.mul(Web3Utils.toBN(MONITOR_VALIDATOR_FOREIGN_TX_LIMIT))
|
2019-07-12 19:10:17 +03:00
|
|
|
|
2019-05-30 21:05:36 +03:00
|
|
|
let validatorsMatch = true
|
|
|
|
logger.debug('calling asyncForEach foreignValidators foreignVBalances')
|
|
|
|
await asyncForEach(foreignValidators, async v => {
|
|
|
|
const balance = await web3Foreign.eth.getBalance(v)
|
2019-07-12 19:10:17 +03:00
|
|
|
const leftTx = Web3Utils.toBN(balance)
|
|
|
|
.div(foreignTxCost)
|
|
|
|
.toString(10)
|
2019-05-30 21:05:36 +03:00
|
|
|
foreignVBalances[v] = {
|
|
|
|
balance: Web3Utils.fromWei(balance),
|
|
|
|
leftTx: Number(leftTx),
|
2019-07-12 19:10:17 +03:00
|
|
|
gasPrice: Number(foreignGasPriceGwei)
|
2019-05-30 21:05:36 +03:00
|
|
|
}
|
|
|
|
if (!homeValidators.includes(v)) {
|
|
|
|
validatorsMatch = false
|
|
|
|
foreignVBalances[v].onlyOnForeign = true
|
|
|
|
}
|
|
|
|
})
|
|
|
|
logger.debug('calling asyncForEach homeValidators homeVBalances')
|
|
|
|
await asyncForEach(homeValidators, async v => {
|
|
|
|
const balance = await web3Home.eth.getBalance(v)
|
2019-07-12 19:10:17 +03:00
|
|
|
const leftTx = homeTxCost.isZero()
|
|
|
|
? 999999
|
|
|
|
: Web3Utils.toBN(balance)
|
|
|
|
.div(homeTxCost)
|
|
|
|
.toString(10)
|
2019-05-30 21:05:36 +03:00
|
|
|
homeVBalances[v] = {
|
|
|
|
balance: Web3Utils.fromWei(balance),
|
|
|
|
leftTx: Number(leftTx),
|
2019-07-12 19:10:17 +03:00
|
|
|
gasPrice: Number(homeGasPriceGwei)
|
2019-05-30 21:05:36 +03:00
|
|
|
}
|
|
|
|
if (!foreignValidators.includes(v)) {
|
|
|
|
validatorsMatch = false
|
|
|
|
homeVBalances[v].onlyOnHome = true
|
|
|
|
}
|
|
|
|
})
|
|
|
|
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-08 16:12:02 +03:00
|
|
|
},
|
2019-05-30 21:05:36 +03:00
|
|
|
requiredSignatures: Number(reqSigHome)
|
|
|
|
},
|
|
|
|
foreign: {
|
|
|
|
validators: {
|
|
|
|
...foreignVBalances
|
2019-05-08 16:12:02 +03:00
|
|
|
},
|
2019-05-30 21:05:36 +03:00
|
|
|
requiredSignatures: Number(reqSigForeign)
|
|
|
|
},
|
|
|
|
requiredSignaturesMatch: reqSigHome === reqSigForeign,
|
|
|
|
validatorsMatch,
|
|
|
|
lastChecked: Math.floor(Date.now() / 1000)
|
2019-05-08 16:12:02 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = main
|