Fallback eth_getLogs to explorer API for BSC (#530)

This commit is contained in:
Kirill Fedoseev 2021-03-14 16:39:23 +03:00 committed by GitHub
parent f93ab330cc
commit 818bc4675d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 233 additions and 68 deletions

@ -19,7 +19,7 @@ COPY --from=contracts /mono/contracts/build ./contracts/build
COPY commons/package.json ./commons/
COPY alm/package.json ./alm/
COPY yarn.lock .
RUN NOYARNPOSTINSTALL=1 yarn install --frozen-lockfile --production
RUN NOYARNPOSTINSTALL=1 yarn install --frozen-lockfile
COPY ./commons ./commons
COPY ./alm ./alm

@ -58,6 +58,7 @@
]
},
"devDependencies": {
"eslint-plugin-prettier": "^3.1.3"
"eslint-plugin-prettier": "^3.1.3",
"node-fetch": "^2.6.1"
}
}

@ -3,6 +3,8 @@ const { BRIDGE_VALIDATORS_ABI, HOME_AMB_ABI } = require('commons')
const path = require('path')
require('dotenv').config()
const Web3 = require('web3')
const fetch = require('node-fetch')
const { URL } = require('url')
const fs = require('fs')
@ -10,7 +12,9 @@ const {
COMMON_HOME_RPC_URL,
COMMON_HOME_BRIDGE_ADDRESS,
COMMON_FOREIGN_RPC_URL,
COMMON_FOREIGN_BRIDGE_ADDRESS
COMMON_FOREIGN_BRIDGE_ADDRESS,
ALM_FOREIGN_EXPLORER_API,
ALM_HOME_EXPLORER_API
} = process.env
const generateSnapshot = async (side, url, bridgeAddress) => {
@ -19,6 +23,31 @@ const generateSnapshot = async (side, url, bridgeAddress) => {
const snapshot = {}
const web3 = new Web3(new Web3.providers.HttpProvider(url))
const api = side === 'home' ? ALM_HOME_EXPLORER_API : ALM_FOREIGN_EXPLORER_API
const getPastEventsWithFallback = (contract, eventName, options) =>
contract.getPastEvents(eventName, options).catch(async e => {
if (e.message.includes('exceed maximum block range')) {
const abi = contract.options.jsonInterface.find(abi => abi.type === 'event' && abi.name === eventName)
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))
}))
}
throw e
})
const currentBlockNumber = await web3.eth.getBlockNumber()
snapshot.snapshotBlockNumber = currentBlockNumber
@ -29,10 +58,14 @@ const generateSnapshot = async (side, url, bridgeAddress) => {
const bridgeContract = new web3.eth.Contract(HOME_AMB_ABI, bridgeAddress)
// Save RequiredBlockConfirmationChanged events
let requiredBlockConfirmationChangedEvents = await bridgeContract.getPastEvents('RequiredBlockConfirmationChanged', {
let requiredBlockConfirmationChangedEvents = await getPastEventsWithFallback(
bridgeContract,
'RequiredBlockConfirmationChanged',
{
fromBlock: 0,
toBlock: currentBlockNumber
})
}
)
// In case RequiredBlockConfirmationChanged was not emitted during initialization in early versions of AMB
// manually generate an event for this. Example Sokol - Kovan bridge
@ -59,10 +92,14 @@ const generateSnapshot = async (side, url, bridgeAddress) => {
const validatorContract = new web3.eth.Contract(BRIDGE_VALIDATORS_ABI, validatorAddress)
// Save RequiredSignaturesChanged events
const RequiredSignaturesChangedEvents = await validatorContract.getPastEvents('RequiredSignaturesChanged', {
const RequiredSignaturesChangedEvents = await getPastEventsWithFallback(
validatorContract,
'RequiredSignaturesChanged',
{
fromBlock: 0,
toBlock: currentBlockNumber
})
}
)
snapshot.RequiredSignaturesChanged = RequiredSignaturesChangedEvents.map(e => ({
blockNumber: e.blockNumber,
returnValues: {
@ -71,7 +108,7 @@ const generateSnapshot = async (side, url, bridgeAddress) => {
}))
// Save ValidatorAdded events
const validatorAddedEvents = await validatorContract.getPastEvents('ValidatorAdded', {
const validatorAddedEvents = await getPastEventsWithFallback(validatorContract, 'ValidatorAdded', {
fromBlock: 0,
toBlock: currentBlockNumber
})
@ -85,7 +122,7 @@ const generateSnapshot = async (side, url, bridgeAddress) => {
}))
// Save ValidatorRemoved events
const validatorRemovedEvents = await validatorContract.getPastEvents('ValidatorRemoved', {
const validatorRemovedEvents = await getPastEventsWithFallback(validatorContract, 'ValidatorRemoved', {
fromBlock: 0,
toBlock: currentBlockNumber
})

@ -6,6 +6,7 @@ import {
DOUBLE_EXECUTION_ATTEMPT_ERROR,
EXECUTION_FAILED_ERROR,
EXECUTION_OUT_OF_GAS_ERROR,
FOREIGN_EXPLORER_API,
INCORRECT_CHAIN_ERROR,
VALIDATOR_CONFIRMATION_STATUS
} from '../config/constants'
@ -92,7 +93,13 @@ export const ManualExecutionButton = ({
})
.on('error', async (e: Error, receipt: TransactionReceipt) => {
if (e.message.includes('Transaction has been reverted by the EVM')) {
const successExecutionData = await getSuccessExecutionData(bridge, 'RelayedMessage', library, messageId)
const successExecutionData = await getSuccessExecutionData(
bridge,
'RelayedMessage',
library,
messageId,
FOREIGN_EXPLORER_API
)
if (successExecutionData) {
setExecutionData(successExecutionData)
setError(DOUBLE_EXECUTION_ATTEMPT_ERROR)

@ -4,6 +4,8 @@ import { useStateProvider } from '../state/StateProvider'
import { Contract } from 'web3-eth-contract'
import { getRequiredBlockConfirmations } from '../utils/contract'
import { foreignSnapshotProvider, homeSnapshotProvider, SnapshotProvider } from '../services/SnapshotProvider'
import Web3 from 'web3'
import { FOREIGN_EXPLORER_API, HOME_EXPLORER_API } from '../config/constants'
export interface UseBlockConfirmationsParams {
fromHome: boolean
@ -19,9 +21,11 @@ export const useBlockConfirmations = ({ receipt, fromHome }: UseBlockConfirmatio
contract: Contract,
receipt: TransactionReceipt,
setResult: Function,
snapshotProvider: SnapshotProvider
snapshotProvider: SnapshotProvider,
web3: Web3,
api: string
) => {
const result = await getRequiredBlockConfirmations(contract, receipt.blockNumber, snapshotProvider)
const result = await getRequiredBlockConfirmations(contract, receipt.blockNumber, snapshotProvider, web3, api)
setResult(result)
}
@ -29,10 +33,12 @@ export const useBlockConfirmations = ({ receipt, fromHome }: UseBlockConfirmatio
() => {
const bridgeContract = fromHome ? home.bridgeContract : foreign.bridgeContract
const snapshotProvider = fromHome ? homeSnapshotProvider : foreignSnapshotProvider
if (!bridgeContract || !receipt) return
callRequireBlockConfirmations(bridgeContract, receipt, setBlockConfirmations, snapshotProvider)
const web3 = fromHome ? home.web3 : foreign.web3
const api = fromHome ? HOME_EXPLORER_API : FOREIGN_EXPLORER_API
if (!bridgeContract || !receipt || !web3) return
callRequireBlockConfirmations(bridgeContract, receipt, setBlockConfirmations, snapshotProvider, web3, api)
},
[home.bridgeContract, foreign.bridgeContract, receipt, fromHome]
[home.bridgeContract, foreign.bridgeContract, receipt, fromHome, home.web3, foreign.web3]
)
return {

@ -6,6 +6,7 @@ import { BRIDGE_VALIDATORS_ABI } from '../abis'
import { useStateProvider } from '../state/StateProvider'
import { TransactionReceipt } from 'web3-eth'
import { foreignSnapshotProvider, homeSnapshotProvider, SnapshotProvider } from '../services/SnapshotProvider'
import { FOREIGN_EXPLORER_API, HOME_EXPLORER_API } from '../config/constants'
export interface useValidatorContractParams {
fromHome: boolean
@ -30,10 +31,12 @@ export const useValidatorContract = ({ receipt, fromHome }: useValidatorContract
contract: Maybe<Contract>,
receipt: TransactionReceipt,
setResult: Function,
snapshotProvider: SnapshotProvider
snapshotProvider: SnapshotProvider,
web3: Web3,
api: string
) => {
if (!contract) return
const result = await getRequiredSignatures(contract, receipt.blockNumber, snapshotProvider)
const result = await getRequiredSignatures(contract, receipt.blockNumber, snapshotProvider, web3, api)
setResult(result)
}
@ -41,32 +44,35 @@ export const useValidatorContract = ({ receipt, fromHome }: useValidatorContract
contract: Maybe<Contract>,
receipt: TransactionReceipt,
setResult: Function,
snapshotProvider: SnapshotProvider
snapshotProvider: SnapshotProvider,
web3: Web3,
api: string
) => {
if (!contract) return
const result = await getValidatorList(contract, receipt.blockNumber, snapshotProvider)
const result = await getValidatorList(contract, receipt.blockNumber, snapshotProvider, web3, api)
setResult(result)
}
const web3 = fromHome ? home.web3 : foreign.web3
const api = fromHome ? HOME_EXPLORER_API : FOREIGN_EXPLORER_API
const bridgeContract = fromHome ? home.bridgeContract : foreign.bridgeContract
const snapshotProvider = fromHome ? homeSnapshotProvider : foreignSnapshotProvider
useEffect(
() => {
const web3 = fromHome ? home.web3 : foreign.web3
const bridgeContract = fromHome ? home.bridgeContract : foreign.bridgeContract
if (!web3 || !bridgeContract) return
callValidatorContract(bridgeContract, web3, setValidatorContract)
},
[home.web3, foreign.web3, home.bridgeContract, foreign.bridgeContract, fromHome]
[web3, bridgeContract]
)
useEffect(
() => {
if (!receipt) return
const snapshotProvider = fromHome ? homeSnapshotProvider : foreignSnapshotProvider
callRequiredSignatures(validatorContract, receipt, setRequiredSignatures, snapshotProvider)
callValidatorList(validatorContract, receipt, setValidatorList, snapshotProvider)
if (!web3 || !receipt) return
callRequiredSignatures(validatorContract, receipt, setRequiredSignatures, snapshotProvider, web3, api)
callValidatorList(validatorContract, receipt, setValidatorList, snapshotProvider, web3, api)
},
[validatorContract, receipt, fromHome]
[validatorContract, receipt, web3, snapshotProvider, api]
)
return {

@ -16,7 +16,7 @@ describe('getRequiredBlockConfirmations', () => {
test('Should call requiredBlockConfirmations method if no events present', async () => {
const contract = ({
getPastEvents: () => {
getPastEvents: async () => {
return []
},
methods: methodsBuilder('1')
@ -37,7 +37,7 @@ describe('getRequiredBlockConfirmations', () => {
})
test('Should not call to get events if block number was included in the snapshot', async () => {
const contract = ({
getPastEvents: jest.fn().mockImplementation(() => []),
getPastEvents: jest.fn().mockImplementation(async () => []),
methods: methodsBuilder('3')
} as unknown) as Contract
@ -64,7 +64,7 @@ describe('getRequiredBlockConfirmations', () => {
})
test('Should call to get events if block number was not included in the snapshot', async () => {
const contract = ({
getPastEvents: jest.fn().mockImplementation(() => [
getPastEvents: jest.fn().mockImplementation(async () => [
{
blockNumber: 9,
returnValues: {
@ -102,7 +102,7 @@ describe('getRequiredBlockConfirmations', () => {
})
test('Should use the most updated event', async () => {
const contract = ({
getPastEvents: jest.fn().mockImplementation(() => [
getPastEvents: jest.fn().mockImplementation(async () => [
{
blockNumber: 9,
returnValues: {
@ -141,7 +141,7 @@ describe('getRequiredBlockConfirmations', () => {
describe('getRequiredSignatures', () => {
test('Should not call to get events if block number was included in the snapshot', async () => {
const contract = ({
getPastEvents: jest.fn().mockImplementation(() => [])
getPastEvents: jest.fn().mockImplementation(async () => [])
} as unknown) as Contract
const snapshotProvider = ({
@ -173,7 +173,7 @@ describe('getRequiredSignatures', () => {
})
test('Should call to get events if block number is higher than the snapshot block number', async () => {
const contract = ({
getPastEvents: jest.fn().mockImplementation(() => [
getPastEvents: jest.fn().mockImplementation(async () => [
{
blockNumber: 15,
returnValues: {
@ -216,7 +216,7 @@ describe('getRequiredSignatures', () => {
})
test('Should use the most updated event before the block number', async () => {
const contract = ({
getPastEvents: jest.fn().mockImplementation(() => [
getPastEvents: jest.fn().mockImplementation(async () => [
{
blockNumber: 15,
returnValues: {
@ -270,7 +270,7 @@ describe('getValidatorList', () => {
test('Should return the current validator list if no events found', async () => {
const currentValidators = [validator1, validator2, validator3]
const contract = ({
getPastEvents: jest.fn().mockImplementation(() => []),
getPastEvents: jest.fn().mockImplementation(async () => []),
methods: methodsBuilder(currentValidators)
} as unknown) as Contract
@ -301,7 +301,7 @@ describe('getValidatorList', () => {
test('If validator was added later from snapshot it should not include it', async () => {
const currentValidators = [validator1, validator2, validator3]
const contract = ({
getPastEvents: jest.fn().mockImplementation(() => []),
getPastEvents: jest.fn().mockImplementation(async () => []),
methods: methodsBuilder(currentValidators)
} as unknown) as Contract
@ -340,7 +340,7 @@ describe('getValidatorList', () => {
test('If validator was added later from chain it should not include it', async () => {
const currentValidators = [validator1, validator2, validator3]
const contract = ({
getPastEvents: jest.fn().mockImplementation(event => {
getPastEvents: jest.fn().mockImplementation(async event => {
if (event === 'ValidatorAdded') {
return [
{
@ -385,7 +385,7 @@ describe('getValidatorList', () => {
test('If validator was removed later from snapshot it should include it', async () => {
const currentValidators = [validator1, validator2]
const contract = ({
getPastEvents: jest.fn().mockImplementation(() => []),
getPastEvents: jest.fn().mockImplementation(async () => []),
methods: methodsBuilder(currentValidators)
} as unknown) as Contract
@ -424,7 +424,7 @@ describe('getValidatorList', () => {
test('If validator was removed later from chain it should include it', async () => {
const currentValidators = [validator1, validator2]
const contract = ({
getPastEvents: jest.fn().mockImplementation(event => {
getPastEvents: jest.fn().mockImplementation(async event => {
if (event === 'ValidatorRemoved') {
return [
{

@ -50,7 +50,7 @@ beforeEach(() => {
describe('getFinalizationEvent', () => {
test('should get finalization event and not try to get failed or pending transactions', async () => {
const contract = ({
getPastEvents: () => {
getPastEvents: async () => {
return [event]
}
} as unknown) as Contract
@ -102,7 +102,7 @@ describe('getFinalizationEvent', () => {
})
test('should retry to get finalization event and not try to get failed or pending transactions if foreign to home transaction', async () => {
const contract = ({
getPastEvents: () => {
getPastEvents: async () => {
return []
}
} as unknown) as Contract
@ -147,7 +147,7 @@ describe('getFinalizationEvent', () => {
})
test('should retry to get finalization event and try to get failed and pending transactions if home to foreign transaction', async () => {
const contract = ({
getPastEvents: () => {
getPastEvents: async () => {
return []
},
options: {
@ -199,7 +199,7 @@ describe('getFinalizationEvent', () => {
})
test('should retry to get finalization event and not to try to get failed transaction if pending transactions found if home to foreign transaction', async () => {
const contract = ({
getPastEvents: () => {
getPastEvents: async () => {
return []
},
options: {
@ -258,7 +258,7 @@ describe('getFinalizationEvent', () => {
})
test('should retry to get finalization event even if failed transaction found if home to foreign transaction', async () => {
const contract = ({
getPastEvents: () => {
getPastEvents: async () => {
return []
},
options: {

@ -1,18 +1,33 @@
import { Contract } from 'web3-eth-contract'
import { EventData } from 'web3-eth-contract'
import { SnapshotProvider } from '../services/SnapshotProvider'
import { getLogs } from './explorer'
import Web3 from 'web3'
const getPastEventsWithFallback = (
api: string,
web3: Web3 | null,
contract: Contract,
eventName: string,
options: any
) =>
contract
.getPastEvents(eventName, options)
.catch(() => (api && web3 ? getLogs(api, web3, contract, eventName, options) : []))
export const getRequiredBlockConfirmations = async (
contract: Contract,
blockNumber: number,
snapshotProvider: SnapshotProvider
snapshotProvider: SnapshotProvider,
web3: Web3 | null = null,
api: string = ''
) => {
const eventsFromSnapshot = snapshotProvider.requiredBlockConfirmationEvents(blockNumber)
const snapshotBlockNumber = snapshotProvider.snapshotBlockNumber()
let contractEvents: EventData[] = []
if (blockNumber > snapshotBlockNumber) {
contractEvents = await contract.getPastEvents('RequiredBlockConfirmationChanged', {
contractEvents = await getPastEventsWithFallback(api, web3, contract, 'RequiredBlockConfirmationChanged', {
fromBlock: snapshotBlockNumber + 1,
toBlock: blockNumber
})
@ -38,14 +53,16 @@ export const getValidatorAddress = (contract: Contract) => contract.methods.vali
export const getRequiredSignatures = async (
contract: Contract,
blockNumber: number,
snapshotProvider: SnapshotProvider
snapshotProvider: SnapshotProvider,
web3: Web3 | null = null,
api: string = ''
) => {
const eventsFromSnapshot = snapshotProvider.requiredSignaturesEvents(blockNumber)
const snapshotBlockNumber = snapshotProvider.snapshotBlockNumber()
let contractEvents: EventData[] = []
if (blockNumber > snapshotBlockNumber) {
contractEvents = await contract.getPastEvents('RequiredSignaturesChanged', {
contractEvents = await getPastEventsWithFallback(api, web3, contract, 'RequiredSignaturesChanged', {
fromBlock: snapshotBlockNumber + 1,
toBlock: blockNumber
})
@ -59,7 +76,13 @@ export const getRequiredSignatures = async (
return parseInt(requiredSignatures)
}
export const getValidatorList = async (contract: Contract, blockNumber: number, snapshotProvider: SnapshotProvider) => {
export const getValidatorList = async (
contract: Contract,
blockNumber: number,
snapshotProvider: SnapshotProvider,
web3: Web3 | null = null,
api: string = ''
) => {
const addedEventsFromSnapshot = snapshotProvider.validatorAddedEvents(blockNumber)
const removedEventsFromSnapshot = snapshotProvider.validatorRemovedEvents(blockNumber)
const snapshotBlockNumber = snapshotProvider.snapshotBlockNumber()
@ -67,10 +90,10 @@ export const getValidatorList = async (contract: Contract, blockNumber: number,
const fromBlock = snapshotBlockNumber > blockNumber ? snapshotBlockNumber + 1 : blockNumber
const [currentList, added, removed] = await Promise.all([
contract.methods.validatorList().call(),
contract.getPastEvents('ValidatorAdded', {
getPastEventsWithFallback(api, web3, contract, 'ValidatorAdded', {
fromBlock
}),
contract.getPastEvents('ValidatorRemoved', {
getPastEventsWithFallback(api, web3, contract, 'ValidatorRemoved', {
fromBlock
})
])

@ -7,6 +7,9 @@ import {
MAX_TX_SEARCH_BLOCK_RANGE,
SUBMIT_SIGNATURE_HASH
} from '../config/constants'
import { AbiItem } from 'web3-utils'
import Web3 from 'web3'
import { Contract } from 'web3-eth-contract'
export interface APITransaction {
timeStamp: string
@ -47,10 +50,15 @@ export interface GetTransactionParams extends GetPendingTransactionParams {
}
export const fetchAccountTransactions = async ({ account, startBlock, endBlock, api }: AccountTransactionsParams) => {
const params = `module=account&action=txlist&address=${account}&filterby=from&startblock=${startBlock}&endblock=${endBlock}`
const url = api.includes('blockscout') ? `${api}?${params}` : `${api}&${params}`
const url = new URL(api)
url.searchParams.append('module', 'account')
url.searchParams.append('action', 'txlist')
url.searchParams.append('address', account)
url.searchParams.append('filterby', 'from')
url.searchParams.append('startblock', startBlock.toString())
url.searchParams.append('endblock', endBlock.toString())
const result = await fetch(url).then(res => res.json())
const result = await fetch(url.toString()).then(res => res.json())
if (result.message === 'No transactions found') {
return []
@ -66,10 +74,13 @@ export const fetchPendingTransactions = async ({
if (!api.includes('blockscout')) {
return []
}
const url = `${api}?module=account&action=pendingtxlist&address=${account}`
const url = new URL(api)
url.searchParams.append('module', 'account')
url.searchParams.append('action', 'pendingtxlist')
url.searchParams.append('address', account)
try {
const result = await fetch(url).then(res => res.json())
const result = await fetch(url.toString()).then(res => res.json())
if (result.status === '0') {
return []
}
@ -85,9 +96,13 @@ export const getClosestBlockByTimestamp = async (api: string, timestamp: number)
throw new Error('Blockscout does not support getblocknobytime')
}
const url = `${api}&module=block&action=getblocknobytime&timestamp=${timestamp}&closest=before`
const url = new URL(api)
url.searchParams.append('module', 'block')
url.searchParams.append('action', 'getblocknobytime')
url.searchParams.append('timestamp', timestamp.toString())
url.searchParams.append('closest', 'before')
const blockNumber = await fetch(url).then(res => res.json())
const blockNumber = await fetch(url.toString()).then(res => res.json())
return parseInt(blockNumber.result)
}
@ -144,6 +159,41 @@ export const getAccountTransactions = async ({
return transactionsCache[key].transactions
}
export const getLogs = async (
api: string,
web3: Web3,
contract: Contract,
event: string,
options: { fromBlock: number; toBlock: number | 'latest'; topics: (string | null)[] }
) => {
const abi = contract.options.jsonInterface.find((abi: AbiItem) => abi.type === 'event' && abi.name === 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.toString())
url.searchParams.append('toBlock', options.toBlock.toString() || 'latest')
const topics = [web3.eth.abi.encodeEventSignature(abi), ...(options.topics || [])]
for (let i = 0; i < topics.length; i++) {
if (topics[i] !== null) {
url.searchParams.append(`topic${i}`, topics[i] as string)
for (let j = 0; j < i; j++) {
url.searchParams.append(`topic${j}_${i}_opr`, 'and')
}
}
}
const logs = await fetch(url.toString()).then(res => res.json())
return logs.result.map((log: any) => ({
transactionHash: log.transactionHash,
blockNumber: parseInt(log.blockNumber.slice(2), 16),
returnValues: web3.eth.abi.decodeLog(abi.inputs!, log.data, log.topics.slice(1))
}))
}
const filterReceiver = (to: string) => (tx: APITransaction) => tx.to.toLowerCase() === to.toLowerCase()
export const getFailedTransactions = async (

@ -1,16 +1,45 @@
import { Contract, EventData } from 'web3-eth-contract'
import Web3 from 'web3'
import { CACHE_KEY_EXECUTION_FAILED, VALIDATOR_CONFIRMATION_STATUS } from '../config/constants'
import {
CACHE_KEY_EXECUTION_FAILED,
FOREIGN_EXPLORER_API,
HOME_EXPLORER_API,
VALIDATOR_CONFIRMATION_STATUS
} from '../config/constants'
import { ExecutionData } from '../hooks/useMessageConfirmations'
import { APIPendingTransaction, APITransaction, GetTransactionParams, GetPendingTransactionParams } from './explorer'
import {
APIPendingTransaction,
APITransaction,
GetTransactionParams,
GetPendingTransactionParams,
getLogs
} from './explorer'
import { getBlock, MessageObject } from './web3'
import validatorsCache from '../services/ValidatorsCache'
import { foreignBlockNumberProvider, homeBlockNumberProvider } from '../services/BlockNumberProvider'
export const getSuccessExecutionData = async (contract: Contract, eventName: string, web3: Web3, messageId: string) => {
const getPastEventsWithFallback = (api: string, web3: Web3, contract: Contract, eventName: string, options: any) =>
contract.getPastEvents(eventName, options).catch(
() =>
api
? getLogs(api, web3, contract, eventName, {
fromBlock: options.fromBlock,
toBlock: options.toBlock,
topics: [null, null, options.filter.messageId]
})
: []
)
export const getSuccessExecutionData = async (
contract: Contract,
eventName: string,
web3: Web3,
messageId: string,
api: string = ''
) => {
// Since it filters by the message id, only one event will be fetched
// so there is no need to limit the range of the block to reduce the network traffic
const events: EventData[] = await contract.getPastEvents(eventName, {
const events: EventData[] = await getPastEventsWithFallback(api, web3, contract, eventName, {
fromBlock: 0,
toBlock: 'latest',
filter: {
@ -57,7 +86,8 @@ export const getFinalizationEvent = async (
setExecutionEventsFetched: Function
) => {
if (!contract || !web3 || !waitingBlocksResolved) return
const successExecutionData = await getSuccessExecutionData(contract, eventName, web3, message.id)
const api = fromHome ? FOREIGN_EXPLORER_API : HOME_EXPLORER_API
const successExecutionData = await getSuccessExecutionData(contract, eventName, web3, message.id, api)
if (successExecutionData) {
setResult(successExecutionData)
} else {

@ -13953,6 +13953,11 @@ node-fetch@^2.1.2, node-fetch@^2.3.0, node-fetch@^2.5.0:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
node-fetch@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-forge@0.7.5:
version "0.7.5"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"