Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add safe getPastEvents with variable block ranges #27

Merged
merged 1 commit into from
May 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions alerts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ require('dotenv').config()
const Web3 = require('web3')
const logger = require('./logger')('alerts')
const eventsInfo = require('./utils/events')
const { getBlockNumber } = require('./utils/contract')

const { HOME_RPC_URL, FOREIGN_RPC_URL } = process.env

Expand All @@ -24,10 +25,7 @@ async function main() {
const xAffirmations = homeWithdrawals.filter(findDifferences(foreignWithdrawals))

logger.debug('building misbehavior blocks')
const getBlockNumber = web3 => web3.eth.getBlockNumber()
const [foreignBlockNumber, homeBlockNumber] = (await Promise.all(
[web3Foreign, web3Home].map(getBlockNumber)
)).map(Web3.utils.toBN)
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)

const baseRange = [false, false, false, false, false]
const xSignaturesMisbehavior = buildRangesObject(
Expand Down
53 changes: 41 additions & 12 deletions getShortEventStats.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
require('dotenv').config()
const Web3 = require('web3')
const { toBN } = require('web3').utils
const logger = require('./logger')('getShortEventStats.js')
const { getBridgeABIs, BRIDGE_MODES, ERC_TYPES } = require('./utils/bridgeMode')

const { HOME_RPC_URL, FOREIGN_RPC_URL, HOME_BRIDGE_ADDRESS, FOREIGN_BRIDGE_ADDRESS } = process.env
const HOME_DEPLOYMENT_BLOCK = Number(process.env.HOME_DEPLOYMENT_BLOCK) || 0
const FOREIGN_DEPLOYMENT_BLOCK = Number(process.env.FOREIGN_DEPLOYMENT_BLOCK) || 0
const HOME_DEPLOYMENT_BLOCK = toBN(Number(process.env.HOME_DEPLOYMENT_BLOCK) || 0)
const FOREIGN_DEPLOYMENT_BLOCK = toBN(Number(process.env.FOREIGN_DEPLOYMENT_BLOCK) || 0)

const homeProvider = new Web3.providers.HttpProvider(HOME_RPC_URL)
const web3Home = new Web3(homeProvider)
Expand All @@ -15,6 +16,7 @@ const web3Foreign = new Web3(foreignProvider)

const ERC20_ABI = require('./abis/ERC20.abi')
const { getTokenType } = require('./utils/ercUtils')
const { getPastEvents, getBlockNumber } = require('./utils/contract')

async function main(bridgeMode) {
try {
Expand All @@ -25,27 +27,54 @@ async function main(bridgeMode) {
const erc20Address = await foreignBridge.methods[erc20MethodName]().call()
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
const tokenType = await getTokenType(foreignBridge, FOREIGN_BRIDGE_ADDRESS)

logger.debug('getting last block numbers')
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
logger.debug("calling homeBridge.getPastEvents('UserRequestForSignature')")
const homeDeposits = await homeBridge.getPastEvents('UserRequestForSignature', {
fromBlock: HOME_DEPLOYMENT_BLOCK
const homeDeposits = await getPastEvents({
contract: homeBridge,
event: 'UserRequestForSignature',
fromBlock: HOME_DEPLOYMENT_BLOCK,
toBlock: homeBlockNumber,
options: {}
})

logger.debug("calling foreignBridge.getPastEvents('RelayedMessage')")
const foreignDeposits = await foreignBridge.getPastEvents('RelayedMessage', {
fromBlock: FOREIGN_DEPLOYMENT_BLOCK
const foreignDeposits = await getPastEvents({
contract: foreignBridge,
event: 'RelayedMessage',
fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
toBlock: foreignBlockNumber,
options: {}
})

logger.debug("calling homeBridge.getPastEvents('AffirmationCompleted')")
const homeWithdrawals = await homeBridge.getPastEvents('AffirmationCompleted', {
fromBlock: HOME_DEPLOYMENT_BLOCK
const homeWithdrawals = await getPastEvents({
contract: homeBridge,
event: 'AffirmationCompleted',
fromBlock: HOME_DEPLOYMENT_BLOCK,
toBlock: homeBlockNumber,
options: {}
})

logger.debug("calling foreignBridge.getPastEvents('UserRequestForAffirmation')")
const foreignWithdrawals =
tokenType === ERC_TYPES.ERC20
? await erc20Contract.getPastEvents('Transfer', {
? await getPastEvents({
contract: erc20Contract,
event: 'Transfer',
fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
filter: { to: FOREIGN_BRIDGE_ADDRESS }
toBlock: foreignBlockNumber,
options: {
filter: { to: FOREIGN_BRIDGE_ADDRESS }
}
})
: await foreignBridge.getPastEvents('UserRequestForAffirmation', {
fromBlock: FOREIGN_DEPLOYMENT_BLOCK
: await getPastEvents({
contract: foreignBridge,
event: 'UserRequestForAffirmation',
fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
toBlock: foreignBlockNumber,
options: {}
})
logger.debug('Done')
return {
Expand Down
50 changes: 50 additions & 0 deletions utils/contract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const { toBN } = require('web3').utils

const ONE = toBN(1)
const TWO = toBN(2)

async function getPastEvents({ contract, event, fromBlock, toBlock, options }) {
let events
try {
events = await contract.getPastEvents(event, {
...options,
fromBlock,
toBlock
})
} catch (e) {
if (e.message.includes('query returned more than 1000 results')) {
const middle = fromBlock.add(toBlock).divRound(TWO)
const middlePlusOne = middle.add(ONE)

const firstHalfEvents = await getPastEvents({
contract,
event,
fromBlock,
toBlock: middle,
options
})
const secondHalfEvents = await getPastEvents({
contract,
event,
fromBlock: middlePlusOne,
toBlock,
options
})
events = [...firstHalfEvents, ...secondHalfEvents]
} else {
throw new Error(e)
}
}
return events
}

const getBlockNumberCall = web3 => web3.eth.getBlockNumber()

async function getBlockNumber(web3Home, web3Foreign) {
return (await Promise.all([web3Home, web3Foreign].map(getBlockNumberCall))).map(toBN)
}

module.exports = {
getPastEvents,
getBlockNumber
}
50 changes: 38 additions & 12 deletions utils/events.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
require('dotenv').config()
const Web3 = require('web3')
const { toBN } = require('web3').utils
const logger = require('../logger')('eventsUtils')
const { BRIDGE_MODES, decodeBridgeMode, getBridgeABIs, ERC_TYPES } = require('./bridgeMode')
const { getTokenType } = require('./ercUtils')

const { HOME_RPC_URL, FOREIGN_RPC_URL, HOME_BRIDGE_ADDRESS, FOREIGN_BRIDGE_ADDRESS } = process.env
const HOME_DEPLOYMENT_BLOCK = Number(process.env.HOME_DEPLOYMENT_BLOCK) || 0
const FOREIGN_DEPLOYMENT_BLOCK = Number(process.env.FOREIGN_DEPLOYMENT_BLOCK) || 0
const HOME_DEPLOYMENT_BLOCK = toBN(Number(process.env.HOME_DEPLOYMENT_BLOCK) || 0)
const FOREIGN_DEPLOYMENT_BLOCK = toBN(Number(process.env.FOREIGN_DEPLOYMENT_BLOCK) || 0)

const homeProvider = new Web3.providers.HttpProvider(HOME_RPC_URL)
const web3Home = new Web3(homeProvider)
Expand All @@ -16,6 +17,7 @@ const web3Foreign = new Web3(foreignProvider)

const HOME_ERC_TO_ERC_ABI = require('../abis/HomeBridgeErcToErc.abi')
const ERC20_ABI = require('../abis/ERC20.abi')
const { getPastEvents, getBlockNumber } = require('./contract')

async function main() {
try {
Expand All @@ -31,29 +33,53 @@ async function main() {
const erc20Address = await foreignBridge.methods[erc20MethodName]().call()
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)

logger.debug('getting last block numbers')
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)

logger.debug("calling homeBridge.getPastEvents('UserRequestForSignature')")
const homeDeposits = await homeBridge.getPastEvents('UserRequestForSignature', {
fromBlock: HOME_DEPLOYMENT_BLOCK
const homeDeposits = await getPastEvents({
contract: homeBridge,
event: 'UserRequestForSignature',
fromBlock: HOME_DEPLOYMENT_BLOCK,
toBlock: homeBlockNumber,
options: {}
})

logger.debug("calling foreignBridge.getPastEvents('RelayedMessage')")
const foreignDeposits = await foreignBridge.getPastEvents('RelayedMessage', {
fromBlock: FOREIGN_DEPLOYMENT_BLOCK
const foreignDeposits = await getPastEvents({
contract: foreignBridge,
event: 'RelayedMessage',
fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
toBlock: foreignBlockNumber,
options: {}
})

logger.debug("calling homeBridge.getPastEvents('AffirmationCompleted')")
const homeWithdrawals = await homeBridge.getPastEvents('AffirmationCompleted', {
fromBlock: HOME_DEPLOYMENT_BLOCK
const homeWithdrawals = await getPastEvents({
contract: homeBridge,
event: 'AffirmationCompleted',
fromBlock: HOME_DEPLOYMENT_BLOCK,
toBlock: homeBlockNumber,
options: {}
})

logger.debug("calling foreignBridge.getPastEvents('UserRequestForAffirmation')")
const foreignWithdrawals = isExternalErc20
? await erc20Contract.getPastEvents('Transfer', {
? await getPastEvents({
contract: erc20Contract,
event: 'Transfer',
fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
filter: { to: FOREIGN_BRIDGE_ADDRESS }
toBlock: foreignBlockNumber,
options: {
filter: { to: FOREIGN_BRIDGE_ADDRESS }
}
})
: await foreignBridge.getPastEvents('UserRequestForAffirmation', {
fromBlock: FOREIGN_DEPLOYMENT_BLOCK
: await getPastEvents({
contract: foreignBridge,
event: 'UserRequestForAffirmation',
fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
toBlock: foreignBlockNumber,
options: {}
})
logger.debug('Done')
return {
Expand Down
11 changes: 9 additions & 2 deletions utils/validatorUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const bridgeValidatorsAbi = require('../abis/BridgeValidators.abi')
const logger = require('../logger')('validatorsUtils')
const { getPastEvents } = require('./contract')

const parseValidatorEvent = event => {
if (
Expand Down Expand Up @@ -51,7 +52,7 @@ const validatorList = async contract => {
}
}

const getValidatorList = async (address, eth, fromBlock) => {
const getValidatorList = async (address, eth, fromBlock, toBlock) => {
logger.debug('getting validatorList')
const validatorsContract = new eth.Contract(bridgeValidatorsAbi, address)
const validators = await validatorList(validatorsContract)
Expand All @@ -62,7 +63,13 @@ const getValidatorList = async (address, eth, fromBlock) => {

logger.debug('getting validatorsEvents')
const contract = new eth.Contract([], address)
const validatorsEvents = await contract.getPastEvents('allEvents', { fromBlock })
const validatorsEvents = await getPastEvents({
contract,
event: 'allEvents',
fromBlock,
toBlock,
options: {}
})

return processValidatorsEvents(validatorsEvents)
}
Expand Down
10 changes: 8 additions & 2 deletions validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const fetch = require('node-fetch')
const logger = require('./logger')('validators')
const { getBridgeABIs } = require('./utils/bridgeMode')
const { getValidatorList } = require('./utils/validatorUtils')
const { getBlockNumber } = require('./utils/contract')

const {
HOME_RPC_URL,
Expand Down Expand Up @@ -56,6 +57,9 @@ async function main(bridgeMode) {
homeValidatorsAddress
)

logger.debug('getting last block numbers')
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)

logger.debug('calling foreignBridge.methods.validatorContract().call()')
const foreignValidatorsAddress = await foreignBridge.methods.validatorContract().call()
const foreignBridgeValidators = new web3Foreign.eth.Contract(
Expand All @@ -67,14 +71,16 @@ async function main(bridgeMode) {
const foreignValidators = await getValidatorList(
foreignValidatorsAddress,
web3Foreign.eth,
FOREIGN_DEPLOYMENT_BLOCK
FOREIGN_DEPLOYMENT_BLOCK,
foreignBlockNumber
)

logger.debug('calling homeBridgeValidators getValidatorList()')
const homeValidators = await getValidatorList(
homeValidatorsAddress,
web3Home.eth,
HOME_DEPLOYMENT_BLOCK
HOME_DEPLOYMENT_BLOCK,
homeBlockNumber
)

const homeBalances = {}
Expand Down