diff --git a/CONFIGURATION.md b/CONFIGURATION.md index e27ffa03..160ef047 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -86,3 +86,5 @@ MONITOR_HOME_TO_FOREIGN_BLOCK_LIST | File with a list of addresses, separated by 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` MONITOR_HOME_VALIDATORS_BALANCE_ENABLE | If set, defines the list of home validator addresses for which balance should be checked. | `string` MONITOR_FOREIGN_VALIDATORS_BALANCE_ENABLE | If set, defines the list of foreign validator addresses for which balance should be checked. | `string` +MONITOR_HOME_EXPLORER_API | The HTTPS URL of the Home network explorer API. If set, may be used as a fallback in case of the RPC node failure. | URL +MONITOR_FOREIGN_EXPLORER_API | The HTTPS URL of the Foreign network explorer API. If set, may be used as a fallback in case of the RPC node failure. | URL \ No newline at end of file diff --git a/commons/abis.js b/commons/abis.js index 0f804095..a04d948d 100644 --- a/commons/abis.js +++ b/commons/abis.js @@ -56,6 +56,11 @@ const OLD_AMB_USER_REQUEST_FOR_SIGNATURE_ABI = [ { anonymous: false, inputs: [ + { + indexed: true, + name: 'messageId', + type: 'bytes32' + }, { indexed: false, name: 'encodedData', @@ -71,6 +76,11 @@ const OLD_AMB_USER_REQUEST_FOR_AFFIRMATION_ABI = [ { anonymous: false, inputs: [ + { + indexed: true, + name: 'messageId', + type: 'bytes32' + }, { indexed: false, name: 'encodedData', diff --git a/monitor/.env.example b/monitor/.env.example index 844f360f..a85e187c 100644 --- a/monitor/.env.example +++ b/monitor/.env.example @@ -28,3 +28,6 @@ MONITOR_HOME_TO_FOREIGN_BLOCK_LIST= # MONITOR_HOME_VALIDATORS_BALANCE_ENABLE=0x... 0x... 0x... # MONITOR_FOREIGN_VALIDATORS_BALANCE_ENABLE=0x... 0x... 0x... + +# MONITOR_HOME_EXPLORER_API= +MONITOR_FOREIGN_EXPLORER_API=https://api.bscscan.com/api?apikey=YourApiKeyToken diff --git a/monitor/utils/web3Cache.js b/monitor/utils/web3Cache.js index b1f6f228..a319d967 100644 --- a/monitor/utils/web3Cache.js +++ b/monitor/utils/web3Cache.js @@ -1,9 +1,15 @@ +const fetch = require('node-fetch') const logger = require('../logger')('web3Cache') const { readCacheFile, writeCacheFile } = require('./file') const { web3Home, web3Foreign } = require('./web3') const { getPastEvents: commonGetPastEvents } = require('../../commons') -const { MONITOR_BRIDGE_NAME, MONITOR_CACHE_EVENTS } = process.env +const { + MONITOR_BRIDGE_NAME, + MONITOR_CACHE_EVENTS, + MONITOR_FOREIGN_EXPLORER_API, + MONITOR_HOME_EXPLORER_API +} = process.env let isDirty = false @@ -52,6 +58,36 @@ async function isForeignContract(address) { return cachedForeignIsContract[address] } +function getPastEventsWithAPIFallback(contract, options) { + return commonGetPastEvents(contract, options).catch(async e => { + const [api, web3] = + options.chain === 'home' ? [MONITOR_HOME_EXPLORER_API, web3Home] : [MONITOR_FOREIGN_EXPLORER_API, web3Foreign] + if (api && e.message.includes('exceed maximum block range')) { + logger.debug('BLOCK RANGE EXCEED, using fallback to the explorer API') + + const abi = contract.options.jsonInterface.find(abi => abi.type === 'event' && abi.name === options.event) + + const url = new URL(api) + url.searchParams.append('module', 'logs') + url.searchParams.append('action', 'getLogs') + url.searchParams.append('address', contract.options.address) + url.searchParams.append('fromBlock', options.fromBlock) + url.searchParams.append('toBlock', options.toBlock || 'latest') + url.searchParams.append('topic0', web3.eth.abi.encodeEventSignature(abi)) + + const logs = await fetch(url).then(res => res.json()) + + return logs.result.map(log => ({ + transactionHash: log.transactionHash, + blockNumber: parseInt(log.blockNumber.slice(2), 16), + returnValues: web3.eth.abi.decodeLog(abi.inputs, log.data, log.topics.slice(1)) + })) + } else { + throw new Error(e) + } + }) +} + async function getPastEvents(contract, options) { if (MONITOR_CACHE_EVENTS !== 'true') { return commonGetPastEvents(contract, options) @@ -94,14 +130,14 @@ async function getPastEvents(contract, options) { // requested: A...B // cached: C...D logger.debug(`Fetching events for blocks ${fromBlock}...${toBlock}`) - result = await commonGetPastEvents(contract, options) + result = await getPastEventsWithAPIFallback(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 })), + ...(await getPastEventsWithAPIFallback(contract, { ...options, toBlock: cachedFromBlock - 1 })), ...cachedEvents.filter(e => e.blockNumber <= toBlock) ] } else if (fromBlock < cachedFromBlock && cachedToBlock < toBlock) { @@ -111,9 +147,9 @@ async function getPastEvents(contract, options) { 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 })), + ...(await getPastEventsWithAPIFallback(contract, { ...options, toBlock: cachedFromBlock - 1 })), ...cachedEvents, - ...(await commonGetPastEvents(contract, { ...options, fromBlock: cachedToBlock + 1 })) + ...(await getPastEventsWithAPIFallback(contract, { ...options, fromBlock: cachedToBlock + 1 })) ] } else if (cachedFromBlock <= fromBlock && toBlock <= cachedToBlock) { // requested: A.B @@ -127,7 +163,7 @@ async function getPastEvents(contract, options) { logger.debug(`Fetching events for blocks ${cachedToBlock + 1}...${toBlock}`) result = [ ...cachedEvents.filter(e => e.blockNumber >= fromBlock), - ...(await commonGetPastEvents(contract, { ...options, fromBlock: cachedToBlock + 1 })) + ...(await getPastEventsWithAPIFallback(contract, { ...options, fromBlock: cachedToBlock + 1 })) ] } else { throw new Error(