Cache fetched events in monitor (#482)
This commit is contained in:
parent
0228fc7d5f
commit
eb1069497a
@ -17,7 +17,7 @@ contracts/build
|
|||||||
oracle/test
|
oracle/test
|
||||||
monitor/test
|
monitor/test
|
||||||
monitor/responses
|
monitor/responses
|
||||||
monitor/cache
|
monitor/cache/*
|
||||||
commons/test
|
commons/test
|
||||||
oracle/**/*.png
|
oracle/**/*.png
|
||||||
oracle/**/*.jpg
|
oracle/**/*.jpg
|
||||||
|
@ -164,7 +164,7 @@ const getPastEvents = async (
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message.includes('query returned more than') && toBlock !== 'latest') {
|
if (e.message.includes('query returned more than') && toBlock !== 'latest') {
|
||||||
const middle = toBN(fromBlock)
|
const middle = toBN(fromBlock)
|
||||||
.add(toBlock)
|
.add(toBN(toBlock))
|
||||||
.divRound(toBN(2))
|
.divRound(toBN(2))
|
||||||
const middlePlusOne = middle.add(toBN(1))
|
const middlePlusOne = middle.add(toBN(1))
|
||||||
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const Web3Utils = require('web3').utils
|
|
||||||
const logger = require('./logger')('alerts')
|
const logger = require('./logger')('alerts')
|
||||||
const eventsInfo = require('./utils/events')
|
const eventsInfo = require('./utils/events')
|
||||||
const { getBlockNumber } = require('./utils/contract')
|
|
||||||
const { processedMsgNotDelivered, eventWithoutReference } = require('./utils/message')
|
const { processedMsgNotDelivered, eventWithoutReference } = require('./utils/message')
|
||||||
const { BRIDGE_MODES } = require('../commons')
|
const { BRIDGE_MODES } = require('../commons')
|
||||||
const { web3Home, web3Foreign } = require('./utils/web3')
|
const { web3Home, web3Foreign, getHomeBlockNumber, getForeignBlockNumber } = require('./utils/web3')
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const {
|
const {
|
||||||
@ -26,7 +24,8 @@ async function main() {
|
|||||||
xAffirmations = foreignToHomeConfirmations.filter(eventWithoutReference(foreignToHomeRequests))
|
xAffirmations = foreignToHomeConfirmations.filter(eventWithoutReference(foreignToHomeRequests))
|
||||||
}
|
}
|
||||||
logger.debug('building misbehavior blocks')
|
logger.debug('building misbehavior blocks')
|
||||||
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
const homeBlockNumber = await getHomeBlockNumber()
|
||||||
|
const foreignBlockNumber = await getForeignBlockNumber()
|
||||||
|
|
||||||
const baseRange = [false, false, false, false, false]
|
const baseRange = [false, false, false, false, false]
|
||||||
const xSignaturesMisbehavior = buildRangesObject(
|
const xSignaturesMisbehavior = buildRangesObject(
|
||||||
@ -66,21 +65,21 @@ async function main() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the location for the blockNumber in a specific range starting from currentBlockNumber
|
* Finds the location for the blockNumber in a specific range starting from currentBlockNumber
|
||||||
* @param {BN} currentBlockNumber
|
* @param {Number} currentBlockNumber
|
||||||
* @returns {function({blockNumber?: *}): boolean[]}
|
* @returns {function({blockNumber?: *}): boolean[]}
|
||||||
*/
|
*/
|
||||||
const findMisbehaviorRange = currentBlockNumber => ({ blockNumber }) => {
|
const findMisbehaviorRange = currentBlockNumber => ({ blockNumber }) => {
|
||||||
const minus60 = currentBlockNumber.sub(Web3Utils.toBN(60))
|
const minus60 = currentBlockNumber - 60
|
||||||
const minus180 = currentBlockNumber.sub(Web3Utils.toBN(180))
|
const minus180 = currentBlockNumber - 180
|
||||||
const minus720 = currentBlockNumber.sub(Web3Utils.toBN(720))
|
const minus720 = currentBlockNumber - 720
|
||||||
const minus17280 = currentBlockNumber.sub(Web3Utils.toBN(17280))
|
const minus17280 = currentBlockNumber - 17280
|
||||||
|
|
||||||
return [
|
return [
|
||||||
minus60.lte(blockNumber),
|
minus60 <= blockNumber,
|
||||||
minus180.lte(blockNumber) && minus60.gt(blockNumber),
|
minus180 <= blockNumber && minus60 > blockNumber,
|
||||||
minus720.lte(blockNumber) && minus180.gt(blockNumber),
|
minus720 <= blockNumber && minus180 > blockNumber,
|
||||||
minus17280.lte(blockNumber) && minus720.gt(blockNumber),
|
minus17280 <= blockNumber && minus720 > blockNumber,
|
||||||
minus17280.gt(blockNumber)
|
minus17280 > blockNumber
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ const { getBridgeMode } = require('../commons')
|
|||||||
const getBalances = require('./getBalances')
|
const getBalances = require('./getBalances')
|
||||||
const getShortEventStats = require('./getShortEventStats')
|
const getShortEventStats = require('./getShortEventStats')
|
||||||
const validators = require('./validators')
|
const validators = require('./validators')
|
||||||
|
const getEventsInfo = require('./utils/events')
|
||||||
const { writeFile, createDir } = require('./utils/file')
|
const { writeFile, createDir } = require('./utils/file')
|
||||||
const { saveCache } = require('./utils/web3Cache')
|
const { saveCache } = require('./utils/web3Cache')
|
||||||
const { web3Home } = require('./utils/web3')
|
const { web3Home } = require('./utils/web3')
|
||||||
@ -23,10 +24,12 @@ async function checkWorker() {
|
|||||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
const bridgeMode = await getBridgeMode(homeBridge)
|
const bridgeMode = await getBridgeMode(homeBridge)
|
||||||
logger.debug('Bridge mode:', bridgeMode)
|
logger.debug('Bridge mode:', bridgeMode)
|
||||||
|
logger.debug('calling getEventsInfo()')
|
||||||
|
const eventsInfo = await getEventsInfo(bridgeMode)
|
||||||
logger.debug('calling getBalances()')
|
logger.debug('calling getBalances()')
|
||||||
const balances = await getBalances(bridgeMode)
|
const balances = await getBalances(bridgeMode, eventsInfo)
|
||||||
logger.debug('calling getShortEventStats()')
|
logger.debug('calling getShortEventStats()')
|
||||||
const events = await getShortEventStats(bridgeMode)
|
const events = await getShortEventStats(bridgeMode, eventsInfo)
|
||||||
const home = Object.assign({}, balances.home, events.home)
|
const home = Object.assign({}, balances.home, events.home)
|
||||||
const foreign = Object.assign({}, balances.foreign, events.foreign)
|
const foreign = Object.assign({}, balances.foreign, events.foreign)
|
||||||
const status = Object.assign({}, balances, events, { home }, { foreign })
|
const status = Object.assign({}, balances, events, { home }, { foreign })
|
||||||
|
@ -3,7 +3,7 @@ const BN = require('bignumber.js')
|
|||||||
const Web3Utils = require('web3').utils
|
const Web3Utils = require('web3').utils
|
||||||
const logger = require('./logger')('getBalances')
|
const logger = require('./logger')('getBalances')
|
||||||
const { BRIDGE_MODES } = require('../commons')
|
const { BRIDGE_MODES } = require('../commons')
|
||||||
const { web3Home, web3Foreign } = require('./utils/web3')
|
const { web3Home, web3Foreign, getHomeBlockNumber } = require('./utils/web3')
|
||||||
|
|
||||||
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
||||||
|
|
||||||
@ -18,21 +18,50 @@ const {
|
|||||||
FOREIGN_NATIVE_TO_ERC_ABI
|
FOREIGN_NATIVE_TO_ERC_ABI
|
||||||
} = require('../commons')
|
} = require('../commons')
|
||||||
|
|
||||||
async function main(bridgeMode) {
|
async function main(bridgeMode, eventsInfo) {
|
||||||
|
const {
|
||||||
|
homeToForeignConfirmations,
|
||||||
|
foreignToHomeConfirmations,
|
||||||
|
homeDelayedBlockNumber,
|
||||||
|
foreignDelayedBlockNumber
|
||||||
|
} = eventsInfo
|
||||||
|
|
||||||
|
// Events in the ./utils/events.js are fetched for different block ranges,
|
||||||
|
// In order to be consistent with the balance values, the following values might be needed
|
||||||
|
|
||||||
|
// Foreign balance should represent all UserRequestForAffirmation events up to block `N - requiredBlockConfirmation()`
|
||||||
|
// and all RelayedMessage events up to block `N`.
|
||||||
|
// This constant tells the difference between bridge balance at block `N - requiredBlockConfirmation() + 1`
|
||||||
|
// and the actual value monitor is interested in.
|
||||||
|
const lateForeignConfirmationsTotalValue = BN.sum(
|
||||||
|
0,
|
||||||
|
...homeToForeignConfirmations.filter(e => e.blockNumber > foreignDelayedBlockNumber).map(e => e.value)
|
||||||
|
)
|
||||||
|
// Home balance should represent all UserRequestForSignature events up to block `M - requiredBlockConfirmation()`
|
||||||
|
// and all AffirmationCompleted events up to block `M`.
|
||||||
|
// This constant tells the difference between bridge balance at block `M - requiredBlockConfirmation() + 1`
|
||||||
|
// and the actual value monitor is interested in.
|
||||||
|
const lateHomeConfirmationsTotalValue = BN.sum(
|
||||||
|
0,
|
||||||
|
...foreignToHomeConfirmations.filter(e => e.blockNumber > homeDelayedBlockNumber).map(e => e.value)
|
||||||
|
)
|
||||||
|
|
||||||
if (bridgeMode === BRIDGE_MODES.ERC_TO_ERC) {
|
if (bridgeMode === BRIDGE_MODES.ERC_TO_ERC) {
|
||||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
const erc20Address = await foreignBridge.methods.erc20token().call()
|
const erc20Address = await foreignBridge.methods.erc20token().call()
|
||||||
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
||||||
logger.debug('calling erc20Contract.methods.balanceOf')
|
logger.debug('calling erc20Contract.methods.balanceOf')
|
||||||
const foreignErc20Balance = await erc20Contract.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
const foreignErc20Balance = await erc20Contract.methods
|
||||||
|
.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
|
.call({}, foreignDelayedBlockNumber)
|
||||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
logger.debug('calling homeBridge.methods.erc677token')
|
logger.debug('calling homeBridge.methods.erc677token')
|
||||||
const tokenAddress = await homeBridge.methods.erc677token().call()
|
const tokenAddress = await homeBridge.methods.erc677token().call()
|
||||||
const tokenContract = new web3Home.eth.Contract(ERC677_ABI, tokenAddress)
|
const tokenContract = new web3Home.eth.Contract(ERC677_ABI, tokenAddress)
|
||||||
logger.debug('calling tokenContract.methods.totalSupply()')
|
logger.debug('calling tokenContract.methods.totalSupply()')
|
||||||
const totalSupply = await tokenContract.methods.totalSupply().call()
|
const totalSupply = await tokenContract.methods.totalSupply().call({}, homeDelayedBlockNumber)
|
||||||
const foreignBalanceBN = new BN(foreignErc20Balance)
|
const foreignBalanceBN = new BN(foreignErc20Balance).plus(lateForeignConfirmationsTotalValue)
|
||||||
const foreignTotalSupplyBN = new BN(totalSupply)
|
const foreignTotalSupplyBN = new BN(totalSupply).plus(lateHomeConfirmationsTotalValue)
|
||||||
const diff = foreignBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
const diff = foreignBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
||||||
logger.debug('Done')
|
logger.debug('Done')
|
||||||
return {
|
return {
|
||||||
@ -49,12 +78,12 @@ async function main(bridgeMode) {
|
|||||||
logger.debug('calling web3Home.eth.getBalance')
|
logger.debug('calling web3Home.eth.getBalance')
|
||||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
const erc20Address = await foreignBridge.methods.erc677token().call()
|
const erc20Address = await foreignBridge.methods.erc677token().call()
|
||||||
const homeBalance = await web3Home.eth.getBalance(COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBalance = await web3Home.eth.getBalance(COMMON_HOME_BRIDGE_ADDRESS, homeDelayedBlockNumber)
|
||||||
const tokenContract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
const tokenContract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
||||||
logger.debug('calling tokenContract.methods.totalSupply()')
|
logger.debug('calling tokenContract.methods.totalSupply()')
|
||||||
const totalSupply = await tokenContract.methods.totalSupply().call()
|
const totalSupply = await tokenContract.methods.totalSupply().call({}, foreignDelayedBlockNumber)
|
||||||
const homeBalanceBN = new BN(homeBalance)
|
const homeBalanceBN = new BN(homeBalance).plus(lateHomeConfirmationsTotalValue)
|
||||||
const foreignTotalSupplyBN = new BN(totalSupply)
|
const foreignTotalSupplyBN = new BN(totalSupply).plus(lateForeignConfirmationsTotalValue)
|
||||||
const diff = homeBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
const diff = homeBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
||||||
logger.debug('Done')
|
logger.debug('Done')
|
||||||
return {
|
return {
|
||||||
@ -91,21 +120,25 @@ async function main(bridgeMode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.debug('calling erc20Contract.methods.balanceOf')
|
logger.debug('calling erc20Contract.methods.balanceOf')
|
||||||
const foreignErc20Balance = await erc20Contract.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
const foreignErc20Balance = await erc20Contract.methods
|
||||||
|
.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
|
.call({}, foreignDelayedBlockNumber)
|
||||||
|
|
||||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_NATIVE_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_NATIVE_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
logger.debug('calling homeBridge.methods.blockRewardContract')
|
logger.debug('calling homeBridge.methods.blockRewardContract')
|
||||||
const blockRewardAddress = await homeBridge.methods.blockRewardContract().call()
|
const blockRewardAddress = await homeBridge.methods.blockRewardContract().call()
|
||||||
const blockRewardContract = new web3Home.eth.Contract(BLOCK_REWARD_ABI, blockRewardAddress)
|
const blockRewardContract = new web3Home.eth.Contract(BLOCK_REWARD_ABI, blockRewardAddress)
|
||||||
|
const homeBlockNumber = await getHomeBlockNumber()
|
||||||
logger.debug('calling blockReward.methods.mintedTotally')
|
logger.debug('calling blockReward.methods.mintedTotally')
|
||||||
const mintedCoins = await blockRewardContract.methods.mintedTotallyByBridge(COMMON_HOME_BRIDGE_ADDRESS).call()
|
const mintedCoins = await blockRewardContract.methods
|
||||||
|
.mintedTotallyByBridge(COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
|
.call({}, homeBlockNumber)
|
||||||
logger.debug('calling homeBridge.methods.totalBurntCoins')
|
logger.debug('calling homeBridge.methods.totalBurntCoins')
|
||||||
const burntCoins = await homeBridge.methods.totalBurntCoins().call()
|
const burntCoins = await homeBridge.methods.totalBurntCoins().call({}, homeDelayedBlockNumber)
|
||||||
|
|
||||||
const mintedCoinsBN = new BN(mintedCoins)
|
const mintedCoinsBN = new BN(mintedCoins)
|
||||||
const burntCoinsBN = new BN(burntCoins)
|
const burntCoinsBN = new BN(burntCoins)
|
||||||
const totalSupplyBN = mintedCoinsBN.minus(burntCoinsBN)
|
const totalSupplyBN = mintedCoinsBN.minus(burntCoinsBN)
|
||||||
const foreignErc20BalanceBN = new BN(foreignErc20Balance)
|
const foreignErc20BalanceBN = new BN(foreignErc20Balance).plus(lateForeignConfirmationsTotalValue)
|
||||||
const investedAmountInDaiBN = new BN(investedAmountInDai)
|
const investedAmountInDaiBN = new BN(investedAmountInDai)
|
||||||
const bridgeDsrBalanceBN = new BN(bridgeDsrBalance)
|
const bridgeDsrBalanceBN = new BN(bridgeDsrBalance)
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const BN = require('bignumber.js')
|
const BN = require('bignumber.js')
|
||||||
const Web3Utils = require('web3').utils
|
const Web3Utils = require('web3').utils
|
||||||
const eventsInfo = require('./utils/events')
|
|
||||||
const { eventWithoutReference, unclaimedHomeToForeignRequests } = require('./utils/message')
|
const { eventWithoutReference, unclaimedHomeToForeignRequests } = require('./utils/message')
|
||||||
const { BRIDGE_MODES } = require('../commons')
|
const { BRIDGE_MODES } = require('../commons')
|
||||||
const { getHomeTxSender } = require('./utils/web3Cache')
|
const { getHomeTxSender } = require('./utils/web3Cache')
|
||||||
@ -12,13 +11,13 @@ const {
|
|||||||
MONITOR_HOME_TO_FOREIGN_CHECK_SENDER
|
MONITOR_HOME_TO_FOREIGN_CHECK_SENDER
|
||||||
} = process.env
|
} = process.env
|
||||||
|
|
||||||
async function main(bridgeMode) {
|
async function main(bridgeMode, eventsInfo) {
|
||||||
const {
|
const {
|
||||||
homeToForeignConfirmations,
|
homeToForeignConfirmations,
|
||||||
homeToForeignRequests,
|
homeToForeignRequests,
|
||||||
foreignToHomeConfirmations,
|
foreignToHomeConfirmations,
|
||||||
foreignToHomeRequests
|
foreignToHomeRequests
|
||||||
} = await eventsInfo(bridgeMode)
|
} = eventsInfo
|
||||||
|
|
||||||
if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
||||||
return {
|
return {
|
||||||
@ -50,7 +49,7 @@ async function main(bridgeMode) {
|
|||||||
|
|
||||||
stats.depositsDiff -= unclaimedPool.length
|
stats.depositsDiff -= unclaimedPool.length
|
||||||
stats.unclaimedDiff = unclaimedPool.length
|
stats.unclaimedDiff = unclaimedPool.length
|
||||||
stats.unclaimedBalance = Web3Utils.fromWei(BN.sum(...unclaimedPool.map(e => e.value)).toFixed())
|
stats.unclaimedBalance = Web3Utils.fromWei(BN.sum(0, ...unclaimedPool.map(e => e.value)).toFixed())
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...stats,
|
...stats,
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
"dotenv": "^5.0.1",
|
"dotenv": "^5.0.1",
|
||||||
"express": "^4.16.3",
|
"express": "^4.16.3",
|
||||||
"node-fetch": "^2.1.2",
|
"node-fetch": "^2.1.2",
|
||||||
"web3": "1.0.0-beta.34"
|
"web3": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10.18"
|
"node": ">= 10.18"
|
||||||
|
@ -12,11 +12,11 @@ cd $(dirname $0)/..
|
|||||||
|
|
||||||
if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
||||||
tstart=`date +"%s"`
|
tstart=`date +"%s"`
|
||||||
|
|
||||||
for file in ${CONFIGDIR}/*.env
|
for file in ${CONFIGDIR}/*.env
|
||||||
do
|
do
|
||||||
echo "${file} handling..."
|
echo "${file} handling..."
|
||||||
|
|
||||||
bridgename=`source ${file} && echo ${MONITOR_BRIDGE_NAME}`
|
bridgename=`source ${file} && echo ${MONITOR_BRIDGE_NAME}`
|
||||||
reportdir=${RESPONSESDIR}"/"${bridgename}
|
reportdir=${RESPONSESDIR}"/"${bridgename}
|
||||||
if [ ! -d ${reportdir} ]; then
|
if [ ! -d ${reportdir} ]; then
|
||||||
@ -38,9 +38,10 @@ if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
|||||||
containername=${bridgename}"-checker"
|
containername=${bridgename}"-checker"
|
||||||
docker container stats --no-stream ${containername} 2>/dev/null 1>&2
|
docker container stats --no-stream ${containername} 2>/dev/null 1>&2
|
||||||
if [ ! "$?" == "0" ]; then
|
if [ ! "$?" == "0" ]; then
|
||||||
|
mkdir -p "$(pwd)/$CACHEDIR/$bridgename"
|
||||||
docker run --rm --env-file $file -v $(pwd)/${RESPONSESDIR}:/mono/monitor/responses \
|
docker run --rm --env-file $file -v $(pwd)/${RESPONSESDIR}:/mono/monitor/responses \
|
||||||
${alist:+"-v"} ${alist:+"$al_param"} ${blist:+"-v"} ${blist:+"$bl_param"} \
|
${alist:+"-v"} ${alist:+"$al_param"} ${blist:+"-v"} ${blist:+"$bl_param"} \
|
||||||
-v $(pwd)/${CACHEDIR}/${bridgename}:/mono/monitor/cache \
|
-v $(pwd)/${CACHEDIR}/${bridgename}:/mono/monitor/cache/${bridgename} \
|
||||||
--name ${containername} poanetwork/tokenbridge-monitor:${IMAGETAG} \
|
--name ${containername} poanetwork/tokenbridge-monitor:${IMAGETAG} \
|
||||||
/bin/bash -c 'yarn check-all'
|
/bin/bash -c 'yarn check-all'
|
||||||
shasum -a 256 -s -c ${checksumfile}
|
shasum -a 256 -s -c ${checksumfile}
|
||||||
@ -57,11 +58,11 @@ if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
|||||||
else
|
else
|
||||||
echo "${containername} have not finished yet" >&2
|
echo "${containername} have not finished yet" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm ${checksumfile}
|
rm ${checksumfile}
|
||||||
echo "========================================"
|
echo "========================================"
|
||||||
done
|
done
|
||||||
|
|
||||||
tend=`date +"%s"`
|
tend=`date +"%s"`
|
||||||
tdiff=`expr ${tend} - ${tstart}`
|
tdiff=`expr ${tend} - ${tstart}`
|
||||||
echo "Total time to run: ${tdiff}"
|
echo "Total time to run: ${tdiff}"
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const logger = require('./logger')('stuckTransfers.js')
|
const logger = require('./logger')('stuckTransfers.js')
|
||||||
const { FOREIGN_V1_ABI } = require('../commons/abis')
|
const { FOREIGN_V1_ABI } = require('../commons/abis')
|
||||||
const { web3Foreign } = require('./utils/web3')
|
const { web3Foreign, getForeignBlockNumber } = require('./utils/web3')
|
||||||
|
const { getPastEvents } = require('./utils/web3Cache')
|
||||||
|
|
||||||
const { COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
const { COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
||||||
const MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
|
const MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
|
||||||
@ -61,38 +62,39 @@ const ABIWithData = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
function compareTransfers(transfersNormal) {
|
function transferWithoutCallback(transfersNormal) {
|
||||||
return withData => {
|
const txHashes = new Set()
|
||||||
return (
|
transfersNormal.forEach(transfer => txHashes.add(transfer.transactionHash))
|
||||||
transfersNormal.filter(normal => {
|
return withData => !txHashes.has(withData.transactionHash)
|
||||||
return normal.transactionHash === withData.transactionHash
|
|
||||||
}).length === 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_V1_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_V1_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
|
logger.debug('calling foreignBridge.methods.erc677token')
|
||||||
const erc20Address = await foreignBridge.methods.erc677token().call()
|
const erc20Address = await foreignBridge.methods.erc677token().call()
|
||||||
const tokenContract = new web3Foreign.eth.Contract(ABITransferWithoutData, erc20Address)
|
const tokenContract = new web3Foreign.eth.Contract(ABITransferWithoutData, erc20Address)
|
||||||
const tokenContractWithData = new web3Foreign.eth.Contract(ABIWithData, erc20Address)
|
const tokenContractWithData = new web3Foreign.eth.Contract(ABIWithData, erc20Address)
|
||||||
|
logger.debug('getting last block number')
|
||||||
|
const foreignBlockNumber = await getForeignBlockNumber()
|
||||||
|
const foreignConfirmations = await foreignBridge.methods.requiredBlockConfirmations().call()
|
||||||
|
const foreignDelayedBlockNumber = foreignBlockNumber - foreignConfirmations
|
||||||
logger.debug('calling tokenContract.getPastEvents Transfer')
|
logger.debug('calling tokenContract.getPastEvents Transfer')
|
||||||
const transfersNormal = await tokenContract.getPastEvents('Transfer', {
|
const options = {
|
||||||
filter: {
|
event: 'Transfer',
|
||||||
to: COMMON_FOREIGN_BRIDGE_ADDRESS
|
options: {
|
||||||
|
filter: {
|
||||||
|
to: COMMON_FOREIGN_BRIDGE_ADDRESS
|
||||||
|
}
|
||||||
},
|
},
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: 'latest'
|
toBlock: foreignBlockNumber,
|
||||||
})
|
chain: 'foreign',
|
||||||
|
safeToBlock: foreignDelayedBlockNumber
|
||||||
|
}
|
||||||
|
const transfersNormal = await getPastEvents(tokenContract, options)
|
||||||
logger.debug('calling tokenContractWithData.getPastEvents Transfer')
|
logger.debug('calling tokenContractWithData.getPastEvents Transfer')
|
||||||
const transfersWithData = await tokenContractWithData.getPastEvents('Transfer', {
|
const transfersWithData = await getPastEvents(tokenContractWithData, options)
|
||||||
filter: {
|
const stuckTransfers = transfersNormal.filter(transferWithoutCallback(transfersWithData))
|
||||||
to: COMMON_FOREIGN_BRIDGE_ADDRESS
|
|
||||||
},
|
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
|
||||||
toBlock: 'latest'
|
|
||||||
})
|
|
||||||
const stuckTransfers = transfersNormal.filter(compareTransfers(transfersWithData))
|
|
||||||
logger.debug('Done')
|
logger.debug('Done')
|
||||||
return {
|
return {
|
||||||
stuckTransfers,
|
stuckTransfers,
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
const { toBN } = require('web3').utils
|
|
||||||
|
|
||||||
const getBlockNumberCall = web3 => web3.eth.getBlockNumber()
|
|
||||||
|
|
||||||
async function getBlockNumber(web3Home, web3Foreign) {
|
|
||||||
return (await Promise.all([web3Home, web3Foreign].map(getBlockNumberCall))).map(toBN)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getBlockNumber
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const { toBN } = require('web3').utils
|
|
||||||
const logger = require('../logger')('eventsUtils')
|
const logger = require('../logger')('eventsUtils')
|
||||||
const {
|
const {
|
||||||
BRIDGE_MODES,
|
BRIDGE_MODES,
|
||||||
@ -10,7 +9,6 @@ const {
|
|||||||
ERC20_ABI,
|
ERC20_ABI,
|
||||||
ERC677_BRIDGE_TOKEN_ABI,
|
ERC677_BRIDGE_TOKEN_ABI,
|
||||||
getTokenType,
|
getTokenType,
|
||||||
getPastEvents,
|
|
||||||
ZERO_ADDRESS,
|
ZERO_ADDRESS,
|
||||||
OLD_AMB_USER_REQUEST_FOR_SIGNATURE_ABI,
|
OLD_AMB_USER_REQUEST_FOR_SIGNATURE_ABI,
|
||||||
OLD_AMB_USER_REQUEST_FOR_AFFIRMATION_ABI
|
OLD_AMB_USER_REQUEST_FOR_AFFIRMATION_ABI
|
||||||
@ -18,13 +16,12 @@ const {
|
|||||||
const { normalizeEventInformation } = require('./message')
|
const { normalizeEventInformation } = require('./message')
|
||||||
const { filterTransferBeforeES } = require('./tokenUtils')
|
const { filterTransferBeforeES } = require('./tokenUtils')
|
||||||
const { writeFile, readCacheFile } = require('./file')
|
const { writeFile, readCacheFile } = require('./file')
|
||||||
const { web3Home, web3Foreign } = require('./web3')
|
const { web3Home, web3Foreign, getHomeBlockNumber, getForeignBlockNumber } = require('./web3')
|
||||||
|
const { getPastEvents } = require('./web3Cache')
|
||||||
|
|
||||||
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS, MONITOR_CACHE_EVENTS } = process.env
|
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS, MONITOR_CACHE_EVENTS } = process.env
|
||||||
const MONITOR_HOME_START_BLOCK = toBN(Number(process.env.MONITOR_HOME_START_BLOCK) || 0)
|
const MONITOR_HOME_START_BLOCK = Number(process.env.MONITOR_HOME_START_BLOCK) || 0
|
||||||
const MONITOR_FOREIGN_START_BLOCK = toBN(Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0)
|
const MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
|
||||||
|
|
||||||
const { getBlockNumber } = require('./contract')
|
|
||||||
|
|
||||||
const cacheFilePath = '/tmp/cachedEvents.json'
|
const cacheFilePath = '/tmp/cachedEvents.json'
|
||||||
async function main(mode) {
|
async function main(mode) {
|
||||||
@ -61,11 +58,12 @@ async function main(mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.debug('getting last block numbers')
|
logger.debug('getting last block numbers')
|
||||||
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
const homeBlockNumber = await getHomeBlockNumber()
|
||||||
const homeConfirmations = toBN(await homeBridge.methods.requiredBlockConfirmations().call())
|
const foreignBlockNumber = await getForeignBlockNumber()
|
||||||
const foreignConfirmations = toBN(await foreignBridge.methods.requiredBlockConfirmations().call())
|
const homeConfirmations = await homeBridge.methods.requiredBlockConfirmations().call()
|
||||||
const homeDelayedBlockNumber = homeBlockNumber.sub(homeConfirmations)
|
const foreignConfirmations = await foreignBridge.methods.requiredBlockConfirmations().call()
|
||||||
const foreignDelayedBlockNumber = foreignBlockNumber.sub(foreignConfirmations)
|
const homeDelayedBlockNumber = homeBlockNumber - homeConfirmations
|
||||||
|
const foreignDelayedBlockNumber = foreignBlockNumber - foreignConfirmations
|
||||||
|
|
||||||
let homeToForeignRequests = []
|
let homeToForeignRequests = []
|
||||||
let foreignToHomeRequests = []
|
let foreignToHomeRequests = []
|
||||||
@ -83,22 +81,24 @@ async function main(mode) {
|
|||||||
homeToForeignRequests = (await getPastEvents(oldHomeBridge, {
|
homeToForeignRequests = (await getPastEvents(oldHomeBridge, {
|
||||||
event: 'UserRequestForSignature',
|
event: 'UserRequestForSignature',
|
||||||
fromBlock: MONITOR_HOME_START_BLOCK,
|
fromBlock: MONITOR_HOME_START_BLOCK,
|
||||||
toBlock: homeDelayedBlockNumber
|
toBlock: homeDelayedBlockNumber,
|
||||||
|
chain: 'home'
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
logger.debug(`found ${homeToForeignRequests.length} events`)
|
logger.debug(`found ${homeToForeignRequests.length} events`)
|
||||||
if (homeToForeignRequests.length > 0) {
|
if (homeToForeignRequests.length > 0) {
|
||||||
homeMigrationBlock = toBN(Math.max(...homeToForeignRequests.map(x => x.blockNumber)))
|
homeMigrationBlock = Math.max(...homeToForeignRequests.map(x => x.blockNumber))
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("calling oldForeignBridge.getPastEvents('UserRequestForAffirmation(bytes)')")
|
logger.debug("calling oldForeignBridge.getPastEvents('UserRequestForAffirmation(bytes)')")
|
||||||
foreignToHomeRequests = (await getPastEvents(oldForeignBridge, {
|
foreignToHomeRequests = (await getPastEvents(oldForeignBridge, {
|
||||||
event: 'UserRequestForAffirmation',
|
event: 'UserRequestForAffirmation',
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignDelayedBlockNumber
|
toBlock: foreignDelayedBlockNumber,
|
||||||
|
chain: 'foreign'
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
logger.debug(`found ${foreignToHomeRequests.length} events`)
|
logger.debug(`found ${foreignToHomeRequests.length} events`)
|
||||||
if (foreignToHomeRequests.length > 0) {
|
if (foreignToHomeRequests.length > 0) {
|
||||||
foreignMigrationBlock = toBN(Math.max(...foreignToHomeRequests.map(x => x.blockNumber)))
|
foreignMigrationBlock = Math.max(...foreignToHomeRequests.map(x => x.blockNumber))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +106,8 @@ async function main(mode) {
|
|||||||
const homeToForeignRequestsNew = (await getPastEvents(homeBridge, {
|
const homeToForeignRequestsNew = (await getPastEvents(homeBridge, {
|
||||||
event: v1Bridge ? 'Deposit' : 'UserRequestForSignature',
|
event: v1Bridge ? 'Deposit' : 'UserRequestForSignature',
|
||||||
fromBlock: homeMigrationBlock,
|
fromBlock: homeMigrationBlock,
|
||||||
toBlock: homeDelayedBlockNumber
|
toBlock: homeDelayedBlockNumber,
|
||||||
|
chain: 'home'
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
homeToForeignRequests = [...homeToForeignRequests, ...homeToForeignRequestsNew]
|
homeToForeignRequests = [...homeToForeignRequests, ...homeToForeignRequestsNew]
|
||||||
|
|
||||||
@ -114,21 +115,26 @@ async function main(mode) {
|
|||||||
const homeToForeignConfirmations = (await getPastEvents(foreignBridge, {
|
const homeToForeignConfirmations = (await getPastEvents(foreignBridge, {
|
||||||
event: v1Bridge ? 'Deposit' : 'RelayedMessage',
|
event: v1Bridge ? 'Deposit' : 'RelayedMessage',
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignBlockNumber
|
toBlock: foreignBlockNumber,
|
||||||
|
chain: 'foreign',
|
||||||
|
safeToBlock: foreignDelayedBlockNumber
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
|
|
||||||
logger.debug("calling homeBridge.getPastEvents('AffirmationCompleted')")
|
logger.debug("calling homeBridge.getPastEvents('AffirmationCompleted')")
|
||||||
const foreignToHomeConfirmations = (await getPastEvents(homeBridge, {
|
const foreignToHomeConfirmations = (await getPastEvents(homeBridge, {
|
||||||
event: v1Bridge ? 'Withdraw' : 'AffirmationCompleted',
|
event: v1Bridge ? 'Withdraw' : 'AffirmationCompleted',
|
||||||
fromBlock: MONITOR_HOME_START_BLOCK,
|
fromBlock: MONITOR_HOME_START_BLOCK,
|
||||||
toBlock: homeBlockNumber
|
toBlock: homeBlockNumber,
|
||||||
|
chain: 'home',
|
||||||
|
safeToBlock: homeDelayedBlockNumber
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
|
|
||||||
logger.debug("calling foreignBridge.getPastEvents('UserRequestForAffirmation')")
|
logger.debug("calling foreignBridge.getPastEvents('UserRequestForAffirmation')")
|
||||||
const foreignToHomeRequestsNew = (await getPastEvents(foreignBridge, {
|
const foreignToHomeRequestsNew = (await getPastEvents(foreignBridge, {
|
||||||
event: v1Bridge ? 'Withdraw' : 'UserRequestForAffirmation',
|
event: v1Bridge ? 'Withdraw' : 'UserRequestForAffirmation',
|
||||||
fromBlock: foreignMigrationBlock,
|
fromBlock: foreignMigrationBlock,
|
||||||
toBlock: foreignDelayedBlockNumber
|
toBlock: foreignDelayedBlockNumber,
|
||||||
|
chain: 'foreign'
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
foreignToHomeRequests = [...foreignToHomeRequests, ...foreignToHomeRequestsNew]
|
foreignToHomeRequests = [...foreignToHomeRequests, ...foreignToHomeRequestsNew]
|
||||||
|
|
||||||
@ -140,7 +146,8 @@ async function main(mode) {
|
|||||||
toBlock: foreignDelayedBlockNumber,
|
toBlock: foreignDelayedBlockNumber,
|
||||||
options: {
|
options: {
|
||||||
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
||||||
}
|
},
|
||||||
|
chain: 'foreign'
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
|
|
||||||
let directTransfers = transferEvents
|
let directTransfers = transferEvents
|
||||||
@ -151,7 +158,9 @@ async function main(mode) {
|
|||||||
const tokensSwappedEvents = await getPastEvents(foreignBridge, {
|
const tokensSwappedEvents = await getPastEvents(foreignBridge, {
|
||||||
event: 'TokensSwapped',
|
event: 'TokensSwapped',
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignBlockNumber
|
toBlock: foreignBlockNumber,
|
||||||
|
chain: 'foreign',
|
||||||
|
safeToBlock: foreignDelayedBlockNumber
|
||||||
})
|
})
|
||||||
|
|
||||||
// Get token swap events emitted by foreign bridge
|
// Get token swap events emitted by foreign bridge
|
||||||
@ -190,7 +199,8 @@ async function main(mode) {
|
|||||||
toBlock: foreignDelayedBlockNumber,
|
toBlock: foreignDelayedBlockNumber,
|
||||||
options: {
|
options: {
|
||||||
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
||||||
}
|
},
|
||||||
|
chain: 'foreign'
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
|
|
||||||
// Remove events after the ES
|
// Remove events after the ES
|
||||||
@ -225,7 +235,9 @@ async function main(mode) {
|
|||||||
foreignToHomeConfirmations,
|
foreignToHomeConfirmations,
|
||||||
foreignToHomeRequests,
|
foreignToHomeRequests,
|
||||||
isExternalErc20,
|
isExternalErc20,
|
||||||
bridgeMode
|
bridgeMode,
|
||||||
|
homeDelayedBlockNumber,
|
||||||
|
foreignDelayedBlockNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MONITOR_CACHE_EVENTS === 'true') {
|
if (MONITOR_CACHE_EVENTS === 'true') {
|
||||||
|
@ -38,6 +38,11 @@ function readCacheFile(filePath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function writeCacheFile(filePath, object) {
|
||||||
|
fs.mkdirSync(path.dirname(filePath), { recursive: true })
|
||||||
|
fs.writeFileSync(filePath, JSON.stringify(object))
|
||||||
|
}
|
||||||
|
|
||||||
function readAccessListFile(filePath) {
|
function readAccessListFile(filePath) {
|
||||||
const data = fs.readFileSync(filePath)
|
const data = fs.readFileSync(filePath)
|
||||||
return data
|
return data
|
||||||
@ -52,5 +57,6 @@ module.exports = {
|
|||||||
writeFile,
|
writeFile,
|
||||||
createDir,
|
createDir,
|
||||||
readCacheFile,
|
readCacheFile,
|
||||||
|
writeCacheFile,
|
||||||
readAccessListFile
|
readAccessListFile
|
||||||
}
|
}
|
||||||
|
93
monitor/utils/getValidatorsList.js
Normal file
93
monitor/utils/getValidatorsList.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
const { REWARDABLE_VALIDATORS_ABI, processValidatorsEvents } = require('../../commons')
|
||||||
|
const { getPastEvents } = require('./web3Cache')
|
||||||
|
|
||||||
|
const VALIDATORS_INDEXED_EVENTS_ABI = [
|
||||||
|
{
|
||||||
|
anonymous: false,
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
indexed: true,
|
||||||
|
name: 'validator',
|
||||||
|
type: 'address'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'ValidatorRemoved',
|
||||||
|
type: 'event'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
anonymous: false,
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
indexed: true,
|
||||||
|
name: 'validator',
|
||||||
|
type: 'address'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'ValidatorAdded',
|
||||||
|
type: 'event'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
anonymous: false,
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
indexed: true,
|
||||||
|
name: 'validator',
|
||||||
|
type: 'address'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
indexed: true,
|
||||||
|
name: 'reward',
|
||||||
|
type: 'address'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'ValidatorAdded',
|
||||||
|
type: 'event'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const tryCall = async (method, fallbackValue) => {
|
||||||
|
try {
|
||||||
|
return await method.call()
|
||||||
|
} catch (e) {
|
||||||
|
return fallbackValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getValidatorList = async (address, eth, options) => {
|
||||||
|
const { logger } = options
|
||||||
|
logger.debug('getting validatorList')
|
||||||
|
|
||||||
|
const validatorsContract = new eth.Contract(REWARDABLE_VALIDATORS_ABI, address) // in monitor, BRIDGE_VALIDATORS_ABI was used
|
||||||
|
const validators = await tryCall(validatorsContract.methods.validatorList(), [])
|
||||||
|
|
||||||
|
if (validators.length) {
|
||||||
|
return validators
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug('getting validatorsEvents')
|
||||||
|
|
||||||
|
options.fromBlock = Number(await tryCall(validatorsContract.methods.deployedAtBlock(), 0))
|
||||||
|
|
||||||
|
const contract = new eth.Contract(VALIDATORS_INDEXED_EVENTS_ABI, address)
|
||||||
|
|
||||||
|
const validatorsEvents = [
|
||||||
|
...(await getPastEvents(contract, {
|
||||||
|
event: 'ValidatorAdded(address)',
|
||||||
|
...options
|
||||||
|
})),
|
||||||
|
...(await getPastEvents(contract, {
|
||||||
|
event: 'ValidatorAdded(address,address)',
|
||||||
|
...options
|
||||||
|
})),
|
||||||
|
...(await getPastEvents(contract, {
|
||||||
|
event: 'ValidatorRemoved(address)',
|
||||||
|
...options
|
||||||
|
}))
|
||||||
|
].sort((a, b) => a.blockNumber - b.blockNumber || a.transactionIndex - b.transactionIndex)
|
||||||
|
|
||||||
|
return processValidatorsEvents(validatorsEvents)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getValidatorList
|
||||||
|
}
|
@ -9,7 +9,19 @@ const web3Home = new Web3(homeProvider)
|
|||||||
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
||||||
const web3Foreign = new Web3(foreignProvider)
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
|
function blockNumberWrapper(web3) {
|
||||||
|
let blockNumber = null
|
||||||
|
return async () => {
|
||||||
|
if (!blockNumber) {
|
||||||
|
blockNumber = await web3.eth.getBlockNumber()
|
||||||
|
}
|
||||||
|
return blockNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
web3Home,
|
web3Home,
|
||||||
web3Foreign
|
web3Foreign,
|
||||||
|
getHomeBlockNumber: blockNumberWrapper(web3Home),
|
||||||
|
getForeignBlockNumber: blockNumberWrapper(web3Foreign)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
const logger = require('../logger')('web3Cache')
|
const logger = require('../logger')('web3Cache')
|
||||||
const { readCacheFile, writeFile } = require('./file')
|
const { readCacheFile, writeCacheFile } = require('./file')
|
||||||
const { web3Home } = require('./web3')
|
const { web3Home } = require('./web3')
|
||||||
|
const { getPastEvents: commonGetPastEvents } = require('../../commons')
|
||||||
|
|
||||||
|
const { MONITOR_BRIDGE_NAME, MONITOR_CACHE_EVENTS } = process.env
|
||||||
|
|
||||||
let isDirty = false
|
let isDirty = false
|
||||||
|
|
||||||
const homeTxSendersCacheFile = './cache/homeTxSenders.json'
|
const homeTxSendersCacheFile = `./cache/${MONITOR_BRIDGE_NAME}/home/txSenders.json`
|
||||||
const cachedHomeTxSenders = readCacheFile(homeTxSendersCacheFile) || {}
|
const cachedHomeTxSenders = readCacheFile(homeTxSendersCacheFile) || {}
|
||||||
|
|
||||||
async function getHomeTxSender(txHash) {
|
async function getHomeTxSender(txHash) {
|
||||||
@ -16,14 +19,115 @@ async function getHomeTxSender(txHash) {
|
|||||||
return cachedHomeTxSenders[txHash]
|
return cachedHomeTxSenders[txHash]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getPastEvents(contract, options) {
|
||||||
|
if (MONITOR_CACHE_EVENTS !== 'true') {
|
||||||
|
return commonGetPastEvents(contract, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
const contractAddr = contract.options.address
|
||||||
|
|
||||||
|
let eventSignature
|
||||||
|
if (options.event.includes('(')) {
|
||||||
|
eventSignature = options.event
|
||||||
|
options.event = web3Home.utils.sha3(eventSignature)
|
||||||
|
const eventABI = contract.options.jsonInterface.find(e => e.type === 'event' && e.signature === options.event)
|
||||||
|
if (!eventABI) {
|
||||||
|
throw new Error(`Event ${eventSignature} not found`)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const eventABI = contract.options.jsonInterface.find(
|
||||||
|
e => e.type === 'event' && (e.name === options.event || e.signature === options.event)
|
||||||
|
)
|
||||||
|
if (!eventABI) {
|
||||||
|
throw new Error(`Event ${options.event} not found`)
|
||||||
|
}
|
||||||
|
eventSignature = `${eventABI.name}(${eventABI.inputs.map(i => i.type).join(',')})`
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheFile = `./cache/${MONITOR_BRIDGE_NAME}/${options.chain}/${contractAddr}/${eventSignature}.json`
|
||||||
|
|
||||||
|
const { fromBlock, toBlock } = options
|
||||||
|
const { fromBlock: cachedFromBlock, toBlock: cachedToBlock, events: cachedEvents } = readCacheFile(cacheFile) || {
|
||||||
|
fromBlock: 0,
|
||||||
|
toBlock: 0,
|
||||||
|
events: []
|
||||||
|
}
|
||||||
|
|
||||||
|
let result
|
||||||
|
if (cachedFromBlock > toBlock || fromBlock > cachedToBlock) {
|
||||||
|
// requested: A...B
|
||||||
|
// cached: C...D
|
||||||
|
// OR
|
||||||
|
// requested: A...B
|
||||||
|
// cached: C...D
|
||||||
|
logger.debug(`Fetching events for blocks ${fromBlock}...${toBlock}`)
|
||||||
|
result = await commonGetPastEvents(contract, options)
|
||||||
|
} else if (fromBlock < cachedFromBlock && toBlock <= cachedToBlock) {
|
||||||
|
// requested: A...B
|
||||||
|
// cached: C...D
|
||||||
|
logger.debug(`Cache hit for blocks ${cachedFromBlock}...${toBlock}`)
|
||||||
|
logger.debug(`Fetching events for blocks ${fromBlock}...${cachedFromBlock - 1}`)
|
||||||
|
result = [
|
||||||
|
...(await commonGetPastEvents(contract, { ...options, toBlock: cachedFromBlock - 1 })),
|
||||||
|
...cachedEvents.filter(e => e.blockNumber <= toBlock)
|
||||||
|
]
|
||||||
|
} else if (fromBlock < cachedFromBlock && cachedToBlock < toBlock) {
|
||||||
|
// requested: A.....B
|
||||||
|
// cached: C.D
|
||||||
|
logger.debug(`Cache hit for blocks ${cachedFromBlock}...${cachedToBlock}`)
|
||||||
|
logger.debug(`Fetching events for blocks ${fromBlock}...${cachedFromBlock - 1}`)
|
||||||
|
logger.debug(`Fetching events for blocks ${cachedToBlock + 1}...${toBlock}`)
|
||||||
|
result = [
|
||||||
|
...(await commonGetPastEvents(contract, { ...options, toBlock: cachedFromBlock - 1 })),
|
||||||
|
...cachedEvents,
|
||||||
|
...(await commonGetPastEvents(contract, { ...options, fromBlock: cachedToBlock + 1 }))
|
||||||
|
]
|
||||||
|
} else if (cachedFromBlock <= fromBlock && toBlock <= cachedToBlock) {
|
||||||
|
// requested: A.B
|
||||||
|
// cached: C.....D
|
||||||
|
logger.debug(`Cache hit for blocks ${fromBlock}...${toBlock}`)
|
||||||
|
result = cachedEvents.filter(e => fromBlock <= e.blockNumber && e.blockNumber <= toBlock)
|
||||||
|
} else if (fromBlock >= cachedFromBlock && toBlock > cachedToBlock) {
|
||||||
|
// requested: A...B
|
||||||
|
// cached: C...D
|
||||||
|
logger.debug(`Cache hit for blocks ${fromBlock}...${cachedToBlock}`)
|
||||||
|
logger.debug(`Fetching events for blocks ${cachedToBlock + 1}...${toBlock}`)
|
||||||
|
result = [
|
||||||
|
...cachedEvents.filter(e => e.blockNumber >= fromBlock),
|
||||||
|
...(await commonGetPastEvents(contract, { ...options, fromBlock: cachedToBlock + 1 }))
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`Something is broken with cache resolution for getPastEvents,
|
||||||
|
requested blocks ${fromBlock}...${toBlock},
|
||||||
|
cached blocks ${cachedFromBlock}...${cachedToBlock}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// it is not safe to cache events with too low block confirmations
|
||||||
|
// so, only events from finalized blocks are included into the cache
|
||||||
|
const safeToBlock = options.safeToBlock || toBlock
|
||||||
|
const cacheToSave = result.filter(e => e.blockNumber <= safeToBlock)
|
||||||
|
logger.debug(
|
||||||
|
`Saving events cache for ${MONITOR_BRIDGE_NAME}/${options.chain}/${contractAddr}/${eventSignature} on disk`
|
||||||
|
)
|
||||||
|
writeCacheFile(cacheFile, {
|
||||||
|
fromBlock,
|
||||||
|
toBlock: safeToBlock,
|
||||||
|
events: cacheToSave
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
function saveCache() {
|
function saveCache() {
|
||||||
if (isDirty) {
|
if (isDirty) {
|
||||||
logger.debug('Saving cache on disk')
|
logger.debug('Saving cache on disk')
|
||||||
writeFile(homeTxSendersCacheFile, cachedHomeTxSenders)
|
writeCacheFile(homeTxSendersCacheFile, cachedHomeTxSenders)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getHomeTxSender,
|
getHomeTxSender,
|
||||||
|
getPastEvents,
|
||||||
saveCache
|
saveCache
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ require('dotenv').config()
|
|||||||
const Web3Utils = require('web3').utils
|
const Web3Utils = require('web3').utils
|
||||||
const fetch = require('node-fetch')
|
const fetch = require('node-fetch')
|
||||||
const logger = require('./logger')('validators')
|
const logger = require('./logger')('validators')
|
||||||
const { getBridgeABIs, BRIDGE_VALIDATORS_ABI, getValidatorList, gasPriceFromSupplier } = require('../commons')
|
const { getBridgeABIs, BRIDGE_VALIDATORS_ABI, gasPriceFromSupplier } = require('../commons')
|
||||||
const { getBlockNumber } = require('./utils/contract')
|
const { web3Home, web3Foreign, getHomeBlockNumber, getForeignBlockNumber } = require('./utils/web3')
|
||||||
const { web3Home, web3Foreign } = require('./utils/web3')
|
const { getValidatorList } = require('./utils/getValidatorsList')
|
||||||
|
|
||||||
const {
|
const {
|
||||||
COMMON_HOME_BRIDGE_ADDRESS,
|
COMMON_HOME_BRIDGE_ADDRESS,
|
||||||
@ -18,8 +18,6 @@ const {
|
|||||||
COMMON_FOREIGN_GAS_PRICE_FALLBACK,
|
COMMON_FOREIGN_GAS_PRICE_FALLBACK,
|
||||||
COMMON_FOREIGN_GAS_PRICE_FACTOR
|
COMMON_FOREIGN_GAS_PRICE_FACTOR
|
||||||
} = process.env
|
} = process.env
|
||||||
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
|
|
||||||
const MONITOR_VALIDATOR_HOME_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_HOME_TX_LIMIT) || 0
|
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_VALIDATOR_FOREIGN_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_FOREIGN_TX_LIMIT) || 0
|
||||||
|
|
||||||
@ -49,7 +47,12 @@ async function main(bridgeMode) {
|
|||||||
const homeBridgeValidators = new web3Home.eth.Contract(BRIDGE_VALIDATORS_ABI, homeValidatorsAddress)
|
const homeBridgeValidators = new web3Home.eth.Contract(BRIDGE_VALIDATORS_ABI, homeValidatorsAddress)
|
||||||
|
|
||||||
logger.debug('getting last block numbers')
|
logger.debug('getting last block numbers')
|
||||||
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
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
|
||||||
|
|
||||||
logger.debug('calling foreignBridge.methods.validatorContract().call()')
|
logger.debug('calling foreignBridge.methods.validatorContract().call()')
|
||||||
const foreignValidatorsAddress = await foreignBridge.methods.validatorContract().call()
|
const foreignValidatorsAddress = await foreignBridge.methods.validatorContract().call()
|
||||||
@ -57,16 +60,18 @@ async function main(bridgeMode) {
|
|||||||
|
|
||||||
logger.debug('calling foreignBridgeValidators getValidatorList()')
|
logger.debug('calling foreignBridgeValidators getValidatorList()')
|
||||||
const foreignValidators = (await getValidatorList(foreignValidatorsAddress, web3Foreign.eth, {
|
const foreignValidators = (await getValidatorList(foreignValidatorsAddress, web3Foreign.eth, {
|
||||||
from: MONITOR_FOREIGN_START_BLOCK,
|
toBlock: foreignBlockNumber,
|
||||||
to: foreignBlockNumber,
|
logger,
|
||||||
logger
|
chain: 'foreign',
|
||||||
|
safeToBlock: foreignDelayedBlockNumber
|
||||||
})).map(web3Foreign.utils.toChecksumAddress)
|
})).map(web3Foreign.utils.toChecksumAddress)
|
||||||
|
|
||||||
logger.debug('calling homeBridgeValidators getValidatorList()')
|
logger.debug('calling homeBridgeValidators getValidatorList()')
|
||||||
const homeValidators = (await getValidatorList(homeValidatorsAddress, web3Home.eth, {
|
const homeValidators = (await getValidatorList(homeValidatorsAddress, web3Home.eth, {
|
||||||
from: MONITOR_HOME_START_BLOCK,
|
toBlock: homeBlockNumber,
|
||||||
to: homeBlockNumber,
|
logger,
|
||||||
logger
|
chain: 'home',
|
||||||
|
safeToBlock: homeDelayedBlockNumber
|
||||||
})).map(web3Home.utils.toChecksumAddress)
|
})).map(web3Home.utils.toChecksumAddress)
|
||||||
|
|
||||||
const foreignVBalances = {}
|
const foreignVBalances = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user