Add allowance/block lists support to monitor (#477)
This commit is contained in:
parent
5fa9d21246
commit
f8d85b14de
@ -8,11 +8,16 @@
|
|||||||
**/docs
|
**/docs
|
||||||
**/*.md
|
**/*.md
|
||||||
|
|
||||||
|
monitor/**/*.env*
|
||||||
|
oracle/**/*.env*
|
||||||
|
!**/.env.example
|
||||||
|
|
||||||
contracts/test
|
contracts/test
|
||||||
contracts/build
|
contracts/build
|
||||||
oracle/test
|
oracle/test
|
||||||
monitor/test
|
monitor/test
|
||||||
monitor/responses
|
monitor/responses
|
||||||
|
monitor/cache
|
||||||
commons/test
|
commons/test
|
||||||
oracle/**/*.png
|
oracle/**/*.png
|
||||||
oracle/**/*.jpg
|
oracle/**/*.jpg
|
||||||
|
10
.gitignore
vendored
10
.gitignore
vendored
@ -10,11 +10,8 @@ dist
|
|||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.env
|
*.env*
|
||||||
.env.local
|
!.env.example
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
.idea
|
.idea
|
||||||
.nyc_output
|
.nyc_output
|
||||||
logs/
|
logs/
|
||||||
@ -49,5 +46,6 @@ __pycache__
|
|||||||
|
|
||||||
#monitor
|
#monitor
|
||||||
monitor/responses/*
|
monitor/responses/*
|
||||||
monitor/configs/*.env
|
monitor/cache/*
|
||||||
|
!monitor/cache/.gitkeep
|
||||||
!monitor/.gitkeep
|
!monitor/.gitkeep
|
||||||
|
@ -79,3 +79,6 @@ MONITOR_TX_NUMBER_THRESHOLD | If estimated number of transaction is equal to or
|
|||||||
MONITOR_PORT | The port for the Monitor. | integer
|
MONITOR_PORT | The port for the Monitor. | integer
|
||||||
MONITOR_BRIDGE_NAME | The name to be used in the url path for the bridge | string
|
MONITOR_BRIDGE_NAME | The name to be used in the url path for the bridge | string
|
||||||
MONITOR_CACHE_EVENTS | If set to true, monitor will cache obtained events for other workers runs | `true` / `false`
|
MONITOR_CACHE_EVENTS | If set to true, monitor will cache obtained events for other workers runs | `true` / `false`
|
||||||
|
MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST | File with a list of addresses, separated by newlines. If set, determines the privileged set of accounts whose requests should be automatically processed by the CollectedSignatures watcher. | string
|
||||||
|
MONITOR_HOME_TO_FOREIGN_BLOCK_LIST | File with a list of addresses, separated by newlines. If set, determines the set of accounts whose requests should be marked as unclaimed. Has a lower priority than the `MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST`. | string
|
||||||
|
MONITOR_HOME_TO_FOREIGN_CHECK_SENDER | If set to `true`, instructs the oracle to do an extra check for transaction origin in the block/allowance list. `false` by default. | `true` / `false`
|
||||||
|
@ -22,3 +22,6 @@ COMMON_FOREIGN_GAS_PRICE_FACTOR=1
|
|||||||
MONITOR_TX_NUMBER_THRESHOLD=100
|
MONITOR_TX_NUMBER_THRESHOLD=100
|
||||||
MONITOR_PORT=3003
|
MONITOR_PORT=3003
|
||||||
MONITOR_CACHE_EVENTS=true
|
MONITOR_CACHE_EVENTS=true
|
||||||
|
|
||||||
|
MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST=
|
||||||
|
MONITOR_HOME_TO_FOREIGN_BLOCK_LIST=
|
||||||
|
@ -1,18 +1,11 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const Web3 = require('web3')
|
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 { 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 { COMMON_HOME_RPC_URL, COMMON_FOREIGN_RPC_URL } = process.env
|
|
||||||
|
|
||||||
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
|
||||||
const web3Home = new Web3(homeProvider)
|
|
||||||
|
|
||||||
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
|
||||||
const web3Foreign = new Web3(foreignProvider)
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const {
|
const {
|
||||||
@ -77,10 +70,10 @@ async function main() {
|
|||||||
* @returns {function({blockNumber?: *}): boolean[]}
|
* @returns {function({blockNumber?: *}): boolean[]}
|
||||||
*/
|
*/
|
||||||
const findMisbehaviorRange = currentBlockNumber => ({ blockNumber }) => {
|
const findMisbehaviorRange = currentBlockNumber => ({ blockNumber }) => {
|
||||||
const minus60 = currentBlockNumber.sub(Web3.utils.toBN(60))
|
const minus60 = currentBlockNumber.sub(Web3Utils.toBN(60))
|
||||||
const minus180 = currentBlockNumber.sub(Web3.utils.toBN(180))
|
const minus180 = currentBlockNumber.sub(Web3Utils.toBN(180))
|
||||||
const minus720 = currentBlockNumber.sub(Web3.utils.toBN(720))
|
const minus720 = currentBlockNumber.sub(Web3Utils.toBN(720))
|
||||||
const minus17280 = currentBlockNumber.sub(Web3.utils.toBN(17280))
|
const minus17280 = currentBlockNumber.sub(Web3Utils.toBN(17280))
|
||||||
|
|
||||||
return [
|
return [
|
||||||
minus60.lte(blockNumber),
|
minus60.lte(blockNumber),
|
||||||
|
0
monitor/cache/.gitkeep
vendored
Normal file
0
monitor/cache/.gitkeep
vendored
Normal file
@ -1,21 +1,20 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const Web3 = require('web3')
|
const BN = require('bignumber.js')
|
||||||
const logger = require('./logger')('checkWorker')
|
const logger = require('./logger')('checkWorker')
|
||||||
const { getBridgeMode } = require('../commons')
|
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 { writeFile, createDir } = require('./utils/file')
|
const { writeFile, createDir } = require('./utils/file')
|
||||||
|
const { saveCache } = require('./utils/web3Cache')
|
||||||
|
const { web3Home } = require('./utils/web3')
|
||||||
|
|
||||||
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_HOME_RPC_URL, MONITOR_BRIDGE_NAME } = process.env
|
const { COMMON_HOME_BRIDGE_ADDRESS, MONITOR_BRIDGE_NAME } = process.env
|
||||||
|
|
||||||
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
|
||||||
const MONITOR_TX_NUMBER_THRESHOLD = Number(process.env.MONITOR_TX_NUMBER_THRESHOLD) || 100
|
const MONITOR_TX_NUMBER_THRESHOLD = Number(process.env.MONITOR_TX_NUMBER_THRESHOLD) || 100
|
||||||
|
|
||||||
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
|
||||||
const web3Home = new Web3(homeProvider)
|
|
||||||
|
|
||||||
const { HOME_ERC_TO_ERC_ABI } = require('../commons')
|
const { HOME_ERC_TO_ERC_ABI } = require('../commons')
|
||||||
|
|
||||||
async function checkWorker() {
|
async function checkWorker() {
|
||||||
@ -31,9 +30,13 @@ async function checkWorker() {
|
|||||||
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 })
|
||||||
|
if (status.balanceDiff && status.unclaimedBalance) {
|
||||||
|
status.balanceDiff = new BN(status.balanceDiff).minus(status.unclaimedBalance).toFixed()
|
||||||
|
}
|
||||||
if (!status) throw new Error('status is empty: ' + JSON.stringify(status))
|
if (!status) throw new Error('status is empty: ' + JSON.stringify(status))
|
||||||
status.health = true
|
status.health = true
|
||||||
writeFile(`/responses/${MONITOR_BRIDGE_NAME}/getBalances.json`, status)
|
writeFile(`/responses/${MONITOR_BRIDGE_NAME}/getBalances.json`, status)
|
||||||
|
saveCache()
|
||||||
|
|
||||||
logger.debug('calling validators()')
|
logger.debug('calling validators()')
|
||||||
const vBalances = await validators(bridgeMode)
|
const vBalances = await validators(bridgeMode)
|
||||||
|
@ -3,6 +3,7 @@ const logger = require('./logger')('checkWorker2')
|
|||||||
const eventsStats = require('./eventsStats')
|
const eventsStats = require('./eventsStats')
|
||||||
const alerts = require('./alerts')
|
const alerts = require('./alerts')
|
||||||
const { writeFile, createDir } = require('./utils/file')
|
const { writeFile, createDir } = require('./utils/file')
|
||||||
|
const { saveCache } = require('./utils/web3Cache')
|
||||||
|
|
||||||
const { MONITOR_BRIDGE_NAME } = process.env
|
const { MONITOR_BRIDGE_NAME } = process.env
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ async function checkWorker2() {
|
|||||||
_alerts.ok = !_alerts.executeAffirmations.mostRecentTxHash && !_alerts.executeSignatures.mostRecentTxHash
|
_alerts.ok = !_alerts.executeAffirmations.mostRecentTxHash && !_alerts.executeSignatures.mostRecentTxHash
|
||||||
_alerts.health = true
|
_alerts.health = true
|
||||||
writeFile(`/responses/${MONITOR_BRIDGE_NAME}/alerts.json`, _alerts)
|
writeFile(`/responses/${MONITOR_BRIDGE_NAME}/alerts.json`, _alerts)
|
||||||
|
saveCache()
|
||||||
logger.debug('Done x2')
|
logger.debug('Done x2')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const Web3 = require('web3')
|
|
||||||
const logger = require('./logger')('checkWorker3')
|
const logger = require('./logger')('checkWorker3')
|
||||||
const stuckTransfers = require('./stuckTransfers')
|
const stuckTransfers = require('./stuckTransfers')
|
||||||
const { writeFile, createDir } = require('./utils/file')
|
const { writeFile, createDir } = require('./utils/file')
|
||||||
|
const { web3Home } = require('./utils/web3')
|
||||||
|
|
||||||
const { MONITOR_BRIDGE_NAME, COMMON_HOME_BRIDGE_ADDRESS, COMMON_HOME_RPC_URL } = process.env
|
const { MONITOR_BRIDGE_NAME, COMMON_HOME_BRIDGE_ADDRESS } = process.env
|
||||||
const { getBridgeMode, HOME_NATIVE_TO_ERC_ABI, BRIDGE_MODES } = require('../commons')
|
const { getBridgeMode, HOME_NATIVE_TO_ERC_ABI, BRIDGE_MODES } = require('../commons')
|
||||||
|
|
||||||
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
|
||||||
const web3Home = new Web3(homeProvider)
|
|
||||||
|
|
||||||
async function checkWorker3() {
|
async function checkWorker3() {
|
||||||
try {
|
try {
|
||||||
const homeBridge = new web3Home.eth.Contract(HOME_NATIVE_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBridge = new web3Home.eth.Contract(HOME_NATIVE_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
|
@ -4,11 +4,12 @@ services:
|
|||||||
monitor:
|
monitor:
|
||||||
image: poanetwork/tokenbridge-monitor:latest
|
image: poanetwork/tokenbridge-monitor:latest
|
||||||
ports:
|
ports:
|
||||||
- "${MONITOR_PORT}:${MONITOR_PORT}"
|
- "${MONITOR_PORT}:${MONITOR_PORT}"
|
||||||
env_file: ./.env
|
env_file: ./.env
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
volumes:
|
volumes:
|
||||||
- ./responses:/mono/monitor/responses
|
- ./responses:/mono/monitor/responses
|
||||||
|
- ./cache:/mono/monitor/cache
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint: "yarn start"
|
entrypoint: "yarn start"
|
||||||
|
@ -1,8 +1,20 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const eventsInfo = require('./utils/events')
|
const eventsInfo = require('./utils/events')
|
||||||
const { processedMsgNotDelivered, deliveredMsgNotProcessed, eventWithoutReference } = require('./utils/message')
|
const {
|
||||||
|
processedMsgNotDelivered,
|
||||||
|
deliveredMsgNotProcessed,
|
||||||
|
eventWithoutReference,
|
||||||
|
unclaimedHomeToForeignRequests
|
||||||
|
} = require('./utils/message')
|
||||||
|
const { getHomeTxSender } = require('./utils/web3Cache')
|
||||||
const { BRIDGE_MODES } = require('../commons')
|
const { BRIDGE_MODES } = require('../commons')
|
||||||
|
|
||||||
|
const {
|
||||||
|
MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST,
|
||||||
|
MONITOR_HOME_TO_FOREIGN_BLOCK_LIST,
|
||||||
|
MONITOR_HOME_TO_FOREIGN_CHECK_SENDER
|
||||||
|
} = process.env
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const {
|
const {
|
||||||
homeToForeignRequests,
|
homeToForeignRequests,
|
||||||
@ -33,17 +45,30 @@ async function main() {
|
|||||||
lastChecked: Math.floor(Date.now() / 1000)
|
lastChecked: Math.floor(Date.now() / 1000)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const onlyInHomeDeposits = homeToForeignRequests.filter(eventWithoutReference(homeToForeignConfirmations))
|
let onlyInHomeDeposits = homeToForeignRequests.filter(eventWithoutReference(homeToForeignConfirmations))
|
||||||
const onlyInForeignDeposits = homeToForeignConfirmations.filter(eventWithoutReference(homeToForeignRequests))
|
const onlyInForeignDeposits = homeToForeignConfirmations.filter(eventWithoutReference(homeToForeignRequests))
|
||||||
|
|
||||||
const onlyInHomeWithdrawals = foreignToHomeConfirmations.filter(eventWithoutReference(foreignToHomeRequests))
|
const onlyInHomeWithdrawals = foreignToHomeConfirmations.filter(eventWithoutReference(foreignToHomeRequests))
|
||||||
const onlyInForeignWithdrawals = foreignToHomeRequests.filter(eventWithoutReference(foreignToHomeConfirmations))
|
const onlyInForeignWithdrawals = foreignToHomeRequests.filter(eventWithoutReference(foreignToHomeConfirmations))
|
||||||
|
|
||||||
|
const unclaimedStats = {}
|
||||||
|
if (MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST || MONITOR_HOME_TO_FOREIGN_BLOCK_LIST) {
|
||||||
|
const unclaimedFilter = unclaimedHomeToForeignRequests()
|
||||||
|
if (MONITOR_HOME_TO_FOREIGN_CHECK_SENDER === 'true') {
|
||||||
|
for (let i = 0; i < onlyInHomeDeposits.length; i++) {
|
||||||
|
onlyInHomeDeposits[i].sender = await getHomeTxSender(onlyInHomeDeposits[i].transactionHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unclaimedStats.unclaimedHomeDeposits = onlyInHomeDeposits.filter(unclaimedFilter)
|
||||||
|
onlyInHomeDeposits = onlyInHomeDeposits.filter(e => !unclaimedFilter(e))
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onlyInHomeDeposits,
|
onlyInHomeDeposits,
|
||||||
onlyInForeignDeposits,
|
onlyInForeignDeposits,
|
||||||
onlyInHomeWithdrawals,
|
onlyInHomeWithdrawals,
|
||||||
onlyInForeignWithdrawals,
|
onlyInForeignWithdrawals,
|
||||||
|
...unclaimedStats,
|
||||||
lastChecked: Math.floor(Date.now() / 1000)
|
lastChecked: Math.floor(Date.now() / 1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,11 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const BN = require('bignumber.js')
|
const BN = require('bignumber.js')
|
||||||
const Web3 = require('web3')
|
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 Web3Utils = Web3.utils
|
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
||||||
|
|
||||||
const {
|
|
||||||
COMMON_HOME_RPC_URL,
|
|
||||||
COMMON_FOREIGN_RPC_URL,
|
|
||||||
COMMON_HOME_BRIDGE_ADDRESS,
|
|
||||||
COMMON_FOREIGN_BRIDGE_ADDRESS
|
|
||||||
} = process.env
|
|
||||||
|
|
||||||
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
|
||||||
const web3Home = new Web3(homeProvider)
|
|
||||||
|
|
||||||
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
|
||||||
const web3Foreign = new Web3(foreignProvider)
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ERC20_ABI,
|
ERC20_ABI,
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
const BN = require('bignumber.js')
|
||||||
|
const Web3Utils = require('web3').utils
|
||||||
const eventsInfo = require('./utils/events')
|
const eventsInfo = require('./utils/events')
|
||||||
|
const { eventWithoutReference, unclaimedHomeToForeignRequests } = require('./utils/message')
|
||||||
const { BRIDGE_MODES } = require('../commons')
|
const { BRIDGE_MODES } = require('../commons')
|
||||||
|
const { getHomeTxSender } = require('./utils/web3Cache')
|
||||||
|
|
||||||
|
const {
|
||||||
|
MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST,
|
||||||
|
MONITOR_HOME_TO_FOREIGN_BLOCK_LIST,
|
||||||
|
MONITOR_HOME_TO_FOREIGN_CHECK_SENDER
|
||||||
|
} = process.env
|
||||||
|
|
||||||
async function main(bridgeMode) {
|
async function main(bridgeMode) {
|
||||||
const {
|
const {
|
||||||
@ -24,9 +34,26 @@ async function main(bridgeMode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
const stats = {
|
||||||
depositsDiff: homeToForeignRequests.length - homeToForeignConfirmations.length,
|
depositsDiff: homeToForeignRequests.length - homeToForeignConfirmations.length,
|
||||||
withdrawalDiff: foreignToHomeConfirmations.length - foreignToHomeRequests.length,
|
withdrawalDiff: foreignToHomeConfirmations.length - foreignToHomeRequests.length
|
||||||
|
}
|
||||||
|
if (MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST || MONITOR_HOME_TO_FOREIGN_BLOCK_LIST) {
|
||||||
|
const onlyInHomeDeposits = homeToForeignRequests.filter(eventWithoutReference(homeToForeignConfirmations))
|
||||||
|
if (MONITOR_HOME_TO_FOREIGN_CHECK_SENDER === 'true') {
|
||||||
|
for (let i = 0; i < onlyInHomeDeposits.length; i++) {
|
||||||
|
onlyInHomeDeposits[i].sender = await getHomeTxSender(onlyInHomeDeposits[i].transactionHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const unclaimedPool = onlyInHomeDeposits.filter(unclaimedHomeToForeignRequests())
|
||||||
|
|
||||||
|
stats.depositsDiff -= unclaimedPool.length
|
||||||
|
stats.unclaimedDiff = unclaimedPool.length
|
||||||
|
stats.unclaimedBalance = Web3Utils.fromWei(BN.sum(...unclaimedPool.map(e => e.value)).toFixed())
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...stats,
|
||||||
home: {
|
home: {
|
||||||
deposits: homeToForeignRequests.length,
|
deposits: homeToForeignRequests.length,
|
||||||
withdrawals: foreignToHomeConfirmations.length
|
withdrawals: foreignToHomeConfirmations.length
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bignumber.js": "^6.0.0",
|
"bignumber.js": "^9.0.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^5.0.1",
|
"dotenv": "^5.0.1",
|
||||||
"express": "^4.16.3",
|
"express": "^4.16.3",
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
CONFIGDIR="configs"
|
CONFIGDIR="configs"
|
||||||
RESPONSESDIR="responses"
|
RESPONSESDIR="responses"
|
||||||
|
ACLDIR="access-lists"
|
||||||
|
ALLOWANCEFILE="allowance_list.txt"
|
||||||
|
BLOCKFILE="block_list.txt"
|
||||||
|
CACHEDIR="cache"
|
||||||
IMAGETAG="latest"
|
IMAGETAG="latest"
|
||||||
|
|
||||||
cd $(dirname $0)/..
|
cd $(dirname $0)/..
|
||||||
@ -26,10 +30,17 @@ if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
alist=`source ${file} && echo ${MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST}`
|
||||||
|
blist=`source ${file} && echo ${MONITOR_HOME_TO_FOREIGN_BLOCK_LIST}`
|
||||||
|
al_param="$(pwd)/${ACLDIR}/${bridgename}/${ALLOWANCEFILE}:/mono/monitor/access-lists/allowance_list.txt"
|
||||||
|
bl_param="$(pwd)/${ACLDIR}/${bridgename}/${BLOCKFILE}:/mono/monitor/access-lists/block_list.txt"
|
||||||
|
|
||||||
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
|
||||||
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"} \
|
||||||
|
-v $(pwd)/${CACHEDIR}/${bridgename}:/mono/monitor/cache \
|
||||||
--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,4 +68,4 @@ if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
|||||||
|
|
||||||
else
|
else
|
||||||
echo "Monitor is not running, skipping checks."
|
echo "Monitor is not running, skipping checks."
|
||||||
fi
|
fi
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const Web3 = require('web3')
|
|
||||||
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 { COMMON_FOREIGN_RPC_URL, 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
|
||||||
|
|
||||||
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
|
||||||
const web3Foreign = new Web3(foreignProvider)
|
|
||||||
|
|
||||||
const ABITransferWithoutData = [
|
const ABITransferWithoutData = [
|
||||||
{
|
{
|
||||||
anonymous: false,
|
anonymous: false,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const Web3 = require('web3')
|
|
||||||
const { toBN } = require('web3').utils
|
const { toBN } = require('web3').utils
|
||||||
const logger = require('../logger')('eventsUtils')
|
const logger = require('../logger')('eventsUtils')
|
||||||
const {
|
const {
|
||||||
@ -19,23 +18,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 {
|
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS, MONITOR_CACHE_EVENTS } = process.env
|
||||||
COMMON_HOME_RPC_URL,
|
|
||||||
COMMON_FOREIGN_RPC_URL,
|
|
||||||
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 = toBN(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 = toBN(Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0)
|
||||||
|
|
||||||
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
|
||||||
const web3Home = new Web3(homeProvider)
|
|
||||||
|
|
||||||
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
|
||||||
const web3Foreign = new Web3(foreignProvider)
|
|
||||||
|
|
||||||
const { getBlockNumber } = require('./contract')
|
const { getBlockNumber } = require('./contract')
|
||||||
|
|
||||||
const cacheFilePath = '/tmp/cachedEvents.json'
|
const cacheFilePath = '/tmp/cachedEvents.json'
|
||||||
|
@ -38,9 +38,19 @@ function readCacheFile(filePath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readAccessListFile(filePath) {
|
||||||
|
const data = fs.readFileSync(filePath)
|
||||||
|
return data
|
||||||
|
.toString()
|
||||||
|
.split('\n')
|
||||||
|
.map(addr => addr.trim().toLowerCase())
|
||||||
|
.filter(addr => addr.length === 42)
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
readFile,
|
readFile,
|
||||||
writeFile,
|
writeFile,
|
||||||
createDir,
|
createDir,
|
||||||
readCacheFile
|
readCacheFile,
|
||||||
|
readAccessListFile
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
const { parseAMBMessage } = require('../../commons')
|
const { parseAMBMessage } = require('../../commons')
|
||||||
|
const { readAccessListFile } = require('./file')
|
||||||
|
|
||||||
|
const { MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST, MONITOR_HOME_TO_FOREIGN_BLOCK_LIST } = process.env
|
||||||
|
|
||||||
const keyAMB = e => [e.messageId, e.sender, e.executor].join(',').toLowerCase()
|
const keyAMB = e => [e.messageId, e.sender, e.executor].join(',').toLowerCase()
|
||||||
|
|
||||||
@ -51,9 +54,22 @@ const eventWithoutReference = otherSideEvents => {
|
|||||||
return e => !keys.has(key(e))
|
return e => !keys.has(key(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unclaimedHomeToForeignRequests = () => {
|
||||||
|
if (MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST) {
|
||||||
|
const allowanceList = readAccessListFile(MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST)
|
||||||
|
return e => !allowanceList.includes(e.recipient.toLowerCase()) && !(e.sender && allowanceList.includes(e.sender))
|
||||||
|
} else if (MONITOR_HOME_TO_FOREIGN_BLOCK_LIST) {
|
||||||
|
const blockList = readAccessListFile(MONITOR_HOME_TO_FOREIGN_BLOCK_LIST)
|
||||||
|
return e => blockList.includes(e.recipient.toLowerCase()) || (e.sender && blockList.includes(e.sender))
|
||||||
|
} else {
|
||||||
|
return () => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
deliveredMsgNotProcessed,
|
deliveredMsgNotProcessed,
|
||||||
processedMsgNotDelivered,
|
processedMsgNotDelivered,
|
||||||
normalizeEventInformation,
|
normalizeEventInformation,
|
||||||
eventWithoutReference
|
eventWithoutReference,
|
||||||
|
unclaimedHomeToForeignRequests
|
||||||
}
|
}
|
||||||
|
15
monitor/utils/web3.js
Normal file
15
monitor/utils/web3.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
require('dotenv').config()
|
||||||
|
const Web3 = require('web3')
|
||||||
|
|
||||||
|
const { COMMON_HOME_RPC_URL, COMMON_FOREIGN_RPC_URL } = process.env
|
||||||
|
|
||||||
|
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
||||||
|
const web3Home = new Web3(homeProvider)
|
||||||
|
|
||||||
|
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
||||||
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
web3Home,
|
||||||
|
web3Foreign
|
||||||
|
}
|
29
monitor/utils/web3Cache.js
Normal file
29
monitor/utils/web3Cache.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const logger = require('../logger')('web3Cache')
|
||||||
|
const { readCacheFile, writeFile } = require('./file')
|
||||||
|
const { web3Home } = require('./web3')
|
||||||
|
|
||||||
|
let isDirty = false
|
||||||
|
|
||||||
|
const homeTxSendersCacheFile = './cache/homeTxSenders.json'
|
||||||
|
const cachedHomeTxSenders = readCacheFile(homeTxSendersCacheFile) || {}
|
||||||
|
|
||||||
|
async function getHomeTxSender(txHash) {
|
||||||
|
if (!cachedHomeTxSenders[txHash]) {
|
||||||
|
logger.debug(`Fetching sender for tx ${txHash}`)
|
||||||
|
cachedHomeTxSenders[txHash] = (await web3Home.eth.getTransaction(txHash)).from.toLowerCase()
|
||||||
|
isDirty = true
|
||||||
|
}
|
||||||
|
return cachedHomeTxSenders[txHash]
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCache() {
|
||||||
|
if (isDirty) {
|
||||||
|
logger.debug('Saving cache on disk')
|
||||||
|
writeFile(homeTxSendersCacheFile, cachedHomeTxSenders)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getHomeTxSender,
|
||||||
|
saveCache
|
||||||
|
}
|
@ -1,13 +1,12 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const Web3 = require('web3')
|
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, getValidatorList, gasPriceFromSupplier } = require('../commons')
|
||||||
const { getBlockNumber } = require('./utils/contract')
|
const { getBlockNumber } = require('./utils/contract')
|
||||||
|
const { web3Home, web3Foreign } = require('./utils/web3')
|
||||||
|
|
||||||
const {
|
const {
|
||||||
COMMON_HOME_RPC_URL,
|
|
||||||
COMMON_FOREIGN_RPC_URL,
|
|
||||||
COMMON_HOME_BRIDGE_ADDRESS,
|
COMMON_HOME_BRIDGE_ADDRESS,
|
||||||
COMMON_FOREIGN_BRIDGE_ADDRESS,
|
COMMON_FOREIGN_BRIDGE_ADDRESS,
|
||||||
COMMON_HOME_GAS_PRICE_SUPPLIER_URL,
|
COMMON_HOME_GAS_PRICE_SUPPLIER_URL,
|
||||||
@ -24,14 +23,6 @@ const MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLO
|
|||||||
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
|
||||||
|
|
||||||
const Web3Utils = Web3.utils
|
|
||||||
|
|
||||||
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
|
||||||
const web3Home = new Web3(homeProvider)
|
|
||||||
|
|
||||||
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
|
||||||
const web3Foreign = new Web3(foreignProvider)
|
|
||||||
|
|
||||||
const homeGasPriceSupplierOpts = {
|
const homeGasPriceSupplierOpts = {
|
||||||
speedType: COMMON_HOME_GAS_PRICE_SPEED_TYPE,
|
speedType: COMMON_HOME_GAS_PRICE_SPEED_TYPE,
|
||||||
factor: COMMON_HOME_GAS_PRICE_FACTOR,
|
factor: COMMON_HOME_GAS_PRICE_FACTOR,
|
||||||
|
@ -118,7 +118,10 @@ async function readAccessListFile(fileName, logger) {
|
|||||||
.split('\n')
|
.split('\n')
|
||||||
.map(addr => addr.trim().toLowerCase())
|
.map(addr => addr.trim().toLowerCase())
|
||||||
.filter(addr => addr.length === 42)
|
.filter(addr => addr.length === 42)
|
||||||
logger.info({ fileName }, `Access list was read successfully, ${data.length} addresses found`)
|
logger.info(
|
||||||
|
{ fileName },
|
||||||
|
`Access list was read successfully, ${readAccessLists[fileName].length} addresses found`
|
||||||
|
)
|
||||||
logger.debug({ addresses: readAccessLists[fileName] }, `Read addresses from the file`)
|
logger.debug({ addresses: readAccessLists[fileName] }, `Read addresses from the file`)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
readAccessLists[fileName] = []
|
readAccessLists[fileName] = []
|
||||||
|
@ -5073,6 +5073,11 @@ bignumber.js@^6.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-6.0.0.tgz#bbfa047644609a5af093e9cbd83b0461fa3f6002"
|
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-6.0.0.tgz#bbfa047644609a5af093e9cbd83b0461fa3f6002"
|
||||||
integrity sha512-x247jIuy60/+FtMRvscqfxtVHQf8AGx2hm9c6btkgC0x/hp9yt+teISNhvF8WlwRkCc5yF2fDECH8SIMe8j+GA==
|
integrity sha512-x247jIuy60/+FtMRvscqfxtVHQf8AGx2hm9c6btkgC0x/hp9yt+teISNhvF8WlwRkCc5yF2fDECH8SIMe8j+GA==
|
||||||
|
|
||||||
|
bignumber.js@^9.0.1:
|
||||||
|
version "9.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5"
|
||||||
|
integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==
|
||||||
|
|
||||||
bignumber.js@~8.0.2:
|
bignumber.js@~8.0.2:
|
||||||
version "8.0.2"
|
version "8.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-8.0.2.tgz#d8c4e1874359573b1ef03011a2d861214aeef137"
|
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-8.0.2.tgz#d8c4e1874359573b1ef03011a2d861214aeef137"
|
||||||
|
Loading…
Reference in New Issue
Block a user