Skip to content

Commit

Permalink
Cache fetched events in monitor (#482)
Browse files Browse the repository at this point in the history
  • Loading branch information
k1rill-fedoseev authored Nov 4, 2020
1 parent 0228fc7 commit eb10694
Show file tree
Hide file tree
Showing 17 changed files with 816 additions and 1,162 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contracts/build
oracle/test
monitor/test
monitor/responses
monitor/cache
monitor/cache/*
commons/test
oracle/**/*.png
oracle/**/*.jpg
Expand Down
2 changes: 1 addition & 1 deletion commons/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const getPastEvents = async (
} catch (e) {
if (e.message.includes('query returned more than') && toBlock !== 'latest') {
const middle = toBN(fromBlock)
.add(toBlock)
.add(toBN(toBlock))
.divRound(toBN(2))
const middlePlusOne = middle.add(toBN(1))

Expand Down
27 changes: 13 additions & 14 deletions monitor/alerts.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
require('dotenv').config()
const Web3Utils = require('web3').utils
const logger = require('./logger')('alerts')
const eventsInfo = require('./utils/events')
const { getBlockNumber } = require('./utils/contract')
const { processedMsgNotDelivered, eventWithoutReference } = require('./utils/message')
const { BRIDGE_MODES } = require('../commons')
const { web3Home, web3Foreign } = require('./utils/web3')
const { web3Home, web3Foreign, getHomeBlockNumber, getForeignBlockNumber } = require('./utils/web3')

async function main() {
const {
Expand All @@ -26,7 +24,8 @@ async function main() {
xAffirmations = foreignToHomeConfirmations.filter(eventWithoutReference(foreignToHomeRequests))
}
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 xSignaturesMisbehavior = buildRangesObject(
Expand Down Expand Up @@ -66,21 +65,21 @@ async function main() {

/**
* Finds the location for the blockNumber in a specific range starting from currentBlockNumber
* @param {BN} currentBlockNumber
* @param {Number} currentBlockNumber
* @returns {function({blockNumber?: *}): boolean[]}
*/
const findMisbehaviorRange = currentBlockNumber => ({ blockNumber }) => {
const minus60 = currentBlockNumber.sub(Web3Utils.toBN(60))
const minus180 = currentBlockNumber.sub(Web3Utils.toBN(180))
const minus720 = currentBlockNumber.sub(Web3Utils.toBN(720))
const minus17280 = currentBlockNumber.sub(Web3Utils.toBN(17280))
const minus60 = currentBlockNumber - 60
const minus180 = currentBlockNumber - 180
const minus720 = currentBlockNumber - 720
const minus17280 = currentBlockNumber - 17280

return [
minus60.lte(blockNumber),
minus180.lte(blockNumber) && minus60.gt(blockNumber),
minus720.lte(blockNumber) && minus180.gt(blockNumber),
minus17280.lte(blockNumber) && minus720.gt(blockNumber),
minus17280.gt(blockNumber)
minus60 <= blockNumber,
minus180 <= blockNumber && minus60 > blockNumber,
minus720 <= blockNumber && minus180 > blockNumber,
minus17280 <= blockNumber && minus720 > blockNumber,
minus17280 > blockNumber
]
}

Expand Down
7 changes: 5 additions & 2 deletions monitor/checkWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { getBridgeMode } = require('../commons')
const getBalances = require('./getBalances')
const getShortEventStats = require('./getShortEventStats')
const validators = require('./validators')
const getEventsInfo = require('./utils/events')
const { writeFile, createDir } = require('./utils/file')
const { saveCache } = require('./utils/web3Cache')
const { web3Home } = require('./utils/web3')
Expand All @@ -23,10 +24,12 @@ async function checkWorker() {
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
const bridgeMode = await getBridgeMode(homeBridge)
logger.debug('Bridge mode:', bridgeMode)
logger.debug('calling getEventsInfo()')
const eventsInfo = await getEventsInfo(bridgeMode)
logger.debug('calling getBalances()')
const balances = await getBalances(bridgeMode)
const balances = await getBalances(bridgeMode, eventsInfo)
logger.debug('calling getShortEventStats()')
const events = await getShortEventStats(bridgeMode)
const events = await getShortEventStats(bridgeMode, eventsInfo)
const home = Object.assign({}, balances.home, events.home)
const foreign = Object.assign({}, balances.foreign, events.foreign)
const status = Object.assign({}, balances, events, { home }, { foreign })
Expand Down
63 changes: 48 additions & 15 deletions monitor/getBalances.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const BN = require('bignumber.js')
const Web3Utils = require('web3').utils
const logger = require('./logger')('getBalances')
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

Expand All @@ -18,21 +18,50 @@ const {
FOREIGN_NATIVE_TO_ERC_ABI
} = 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) {
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
const erc20Address = await foreignBridge.methods.erc20token().call()
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
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)
logger.debug('calling homeBridge.methods.erc677token')
const tokenAddress = await homeBridge.methods.erc677token().call()
const tokenContract = new web3Home.eth.Contract(ERC677_ABI, tokenAddress)
logger.debug('calling tokenContract.methods.totalSupply()')
const totalSupply = await tokenContract.methods.totalSupply().call()
const foreignBalanceBN = new BN(foreignErc20Balance)
const foreignTotalSupplyBN = new BN(totalSupply)
const totalSupply = await tokenContract.methods.totalSupply().call({}, homeDelayedBlockNumber)
const foreignBalanceBN = new BN(foreignErc20Balance).plus(lateForeignConfirmationsTotalValue)
const foreignTotalSupplyBN = new BN(totalSupply).plus(lateHomeConfirmationsTotalValue)
const diff = foreignBalanceBN.minus(foreignTotalSupplyBN).toString(10)
logger.debug('Done')
return {
Expand All @@ -49,12 +78,12 @@ async function main(bridgeMode) {
logger.debug('calling web3Home.eth.getBalance')
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
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)
logger.debug('calling tokenContract.methods.totalSupply()')
const totalSupply = await tokenContract.methods.totalSupply().call()
const homeBalanceBN = new BN(homeBalance)
const foreignTotalSupplyBN = new BN(totalSupply)
const totalSupply = await tokenContract.methods.totalSupply().call({}, foreignDelayedBlockNumber)
const homeBalanceBN = new BN(homeBalance).plus(lateHomeConfirmationsTotalValue)
const foreignTotalSupplyBN = new BN(totalSupply).plus(lateForeignConfirmationsTotalValue)
const diff = homeBalanceBN.minus(foreignTotalSupplyBN).toString(10)
logger.debug('Done')
return {
Expand Down Expand Up @@ -91,21 +120,25 @@ async function main(bridgeMode) {
}

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)
logger.debug('calling homeBridge.methods.blockRewardContract')
const blockRewardAddress = await homeBridge.methods.blockRewardContract().call()
const blockRewardContract = new web3Home.eth.Contract(BLOCK_REWARD_ABI, blockRewardAddress)
const homeBlockNumber = await getHomeBlockNumber()
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')
const burntCoins = await homeBridge.methods.totalBurntCoins().call()

const burntCoins = await homeBridge.methods.totalBurntCoins().call({}, homeDelayedBlockNumber)
const mintedCoinsBN = new BN(mintedCoins)
const burntCoinsBN = new BN(burntCoins)
const totalSupplyBN = mintedCoinsBN.minus(burntCoinsBN)
const foreignErc20BalanceBN = new BN(foreignErc20Balance)
const foreignErc20BalanceBN = new BN(foreignErc20Balance).plus(lateForeignConfirmationsTotalValue)
const investedAmountInDaiBN = new BN(investedAmountInDai)
const bridgeDsrBalanceBN = new BN(bridgeDsrBalance)

Expand Down
7 changes: 3 additions & 4 deletions monitor/getShortEventStats.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require('dotenv').config()
const BN = require('bignumber.js')
const Web3Utils = require('web3').utils
const eventsInfo = require('./utils/events')
const { eventWithoutReference, unclaimedHomeToForeignRequests } = require('./utils/message')
const { BRIDGE_MODES } = require('../commons')
const { getHomeTxSender } = require('./utils/web3Cache')
Expand All @@ -12,13 +11,13 @@ const {
MONITOR_HOME_TO_FOREIGN_CHECK_SENDER
} = process.env

async function main(bridgeMode) {
async function main(bridgeMode, eventsInfo) {
const {
homeToForeignConfirmations,
homeToForeignRequests,
foreignToHomeConfirmations,
foreignToHomeRequests
} = await eventsInfo(bridgeMode)
} = eventsInfo

if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
return {
Expand Down Expand Up @@ -50,7 +49,7 @@ async function main(bridgeMode) {

stats.depositsDiff -= 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 {
...stats,
Expand Down
2 changes: 1 addition & 1 deletion monitor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"dotenv": "^5.0.1",
"express": "^4.16.3",
"node-fetch": "^2.1.2",
"web3": "1.0.0-beta.34"
"web3": "^1.3.0"
},
"engines": {
"node": ">= 10.18"
Expand Down
11 changes: 6 additions & 5 deletions monitor/scripts/getBridgeStats.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ cd $(dirname $0)/..

if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
tstart=`date +"%s"`

for file in ${CONFIGDIR}/*.env
do
echo "${file} handling..."

bridgename=`source ${file} && echo ${MONITOR_BRIDGE_NAME}`
reportdir=${RESPONSESDIR}"/"${bridgename}
if [ ! -d ${reportdir} ]; then
Expand All @@ -38,9 +38,10 @@ if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
containername=${bridgename}"-checker"
docker container stats --no-stream ${containername} 2>/dev/null 1>&2
if [ ! "$?" == "0" ]; then
mkdir -p "$(pwd)/$CACHEDIR/$bridgename"
docker run --rm --env-file $file -v $(pwd)/${RESPONSESDIR}:/mono/monitor/responses \
${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} \
/bin/bash -c 'yarn check-all'
shasum -a 256 -s -c ${checksumfile}
Expand All @@ -57,11 +58,11 @@ if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
else
echo "${containername} have not finished yet" >&2
fi

rm ${checksumfile}
echo "========================================"
done

tend=`date +"%s"`
tdiff=`expr ${tend} - ${tstart}`
echo "Total time to run: ${tdiff}"
Expand Down
46 changes: 24 additions & 22 deletions monitor/stuckTransfers.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require('dotenv').config()
const logger = require('./logger')('stuckTransfers.js')
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 MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
Expand Down Expand Up @@ -61,38 +62,39 @@ const ABIWithData = [
}
]

function compareTransfers(transfersNormal) {
return withData => {
return (
transfersNormal.filter(normal => {
return normal.transactionHash === withData.transactionHash
}).length === 0
)
}
function transferWithoutCallback(transfersNormal) {
const txHashes = new Set()
transfersNormal.forEach(transfer => txHashes.add(transfer.transactionHash))
return withData => !txHashes.has(withData.transactionHash)
}

async function main() {
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 tokenContract = new web3Foreign.eth.Contract(ABITransferWithoutData, 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')
const transfersNormal = await tokenContract.getPastEvents('Transfer', {
filter: {
to: COMMON_FOREIGN_BRIDGE_ADDRESS
const options = {
event: 'Transfer',
options: {
filter: {
to: COMMON_FOREIGN_BRIDGE_ADDRESS
}
},
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')
const transfersWithData = await tokenContractWithData.getPastEvents('Transfer', {
filter: {
to: COMMON_FOREIGN_BRIDGE_ADDRESS
},
fromBlock: MONITOR_FOREIGN_START_BLOCK,
toBlock: 'latest'
})
const stuckTransfers = transfersNormal.filter(compareTransfers(transfersWithData))
const transfersWithData = await getPastEvents(tokenContractWithData, options)
const stuckTransfers = transfersNormal.filter(transferWithoutCallback(transfersWithData))
logger.debug('Done')
return {
stuckTransfers,
Expand Down
11 changes: 0 additions & 11 deletions monitor/utils/contract.js

This file was deleted.

Loading

0 comments on commit eb10694

Please sign in to comment.