Skip to content

Commit

Permalink
fix: l2-bridge-mantle fetch withdrawalEvents by pagination method
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeyWh1te committed May 23, 2024
1 parent 70812fd commit deaaefe
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 37 deletions.
85 changes: 68 additions & 17 deletions l2-bridge-mantle/src/clients/mantle_provider.spec.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,79 @@
import { App } from '../app'
import BigNumber from 'bignumber.js'
import { ETH_DECIMALS } from '../utils/constants'
import { Address, ETH_DECIMALS } from '../utils/constants'
import * as E from 'fp-ts/Either'
import * as Winston from 'winston'
import { ethers } from 'ethers'
import { ERC20Short__factory, L2ERC20TokenBridge__factory } from '../generated'
import { MantleClient } from './mantle_provider'
import { AVG_BLOCK_TIME_2SECONDS, HOURS_48 } from '../services/monitor_withdrawals'
import { expect } from '@jest/globals'

const timeout = 120_000

describe('MantleProvider', () => {
test('fetchBlocks', async () => {
const app = await App.getInstance()
test(
'fetchBlocks',
async () => {
const app = await App.getInstance()

const start = 50_183_000
const end = 50_184_000
const blocks = await app.mantleClient.fetchL2Blocks(start, end)

expect(blocks.length).toEqual(end - start + 1)
},
timeout,
)

test(
'getWstEthTotalSupply is 9.860230303930711579 wsETH',
async () => {
const app = await App.getInstance()

const baseBlockNumber = 62_393_461
const balance = await app.mantleClient.getWstEthTotalSupply(baseBlockNumber)
if (E.isLeft(balance)) {
throw balance.left
}

expect(balance.right.dividedBy(ETH_DECIMALS)).toEqual(new BigNumber('9.860230303930711579'))
},
timeout,
)

test(
'getWithdrawalEvents fetches 86_401 blocks for getting withdrawal events',
async () => {
const adr = Address

const logger: Winston.Logger = Winston.createLogger({
format: Winston.format.simple(),
transports: [new Winston.transports.Console()],
})

const mantleRpcURL = 'https://rpc.mantle.xyz'

const baseNetworkID = 5000
const mantleProvider = new ethers.providers.JsonRpcProvider(mantleRpcURL, baseNetworkID)

const l2Bridge = L2ERC20TokenBridge__factory.connect(adr.MANTLE_L2ERC20_TOKEN_BRIDGE_ADDRESS, mantleProvider)
const bridgedWSthEthRunner = ERC20Short__factory.connect(adr.MANTLE_WSTETH_ADDRESS, mantleProvider)
const mantleClient = new MantleClient(mantleProvider, logger, l2Bridge, bridgedWSthEthRunner)

const start = 50_183_000
const end = 50_184_000
const blocks = await app.mantleClient.fetchL2Blocks(start, end)
const currentBlock = 64_170_875

expect(blocks.length).toEqual(end - start + 1)
}, 120_000)
const pastBlock = currentBlock - Math.ceil(HOURS_48 / AVG_BLOCK_TIME_2SECONDS)

test('getWstEthTotalSupply is 9.860230303930711579 wsETH', async () => {
const app = await App.getInstance()
expect(86401).toEqual(currentBlock - pastBlock + 1)

const baseBlockNumber = 62_393_461
const balance = await app.mantleClient.getWstEthTotalSupply(baseBlockNumber)
if (E.isLeft(balance)) {
throw balance.left
}
const withdrawalEvents = await mantleClient.getWithdrawalEvents(pastBlock, currentBlock - 1)
if (E.isLeft(withdrawalEvents)) {
throw withdrawalEvents
}

expect(balance.right.dividedBy(ETH_DECIMALS)).toEqual(new BigNumber('9.860230303930711579'))
}, 120_000)
expect(withdrawalEvents.right.length).toEqual(2)
},
timeout,
)
})
51 changes: 33 additions & 18 deletions l2-bridge-mantle/src/clients/mantle_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export class MantleClient implements IMantleClient, IMonitorWithdrawalsClient, I
const blocks = await doRequest(request)
out.push(...blocks)
} catch (e) {
this.logger.warning(`${e}`)
this.logger.warn(`${e}`)
if (allowedExtraRequest === 0) {
break
}
Expand Down Expand Up @@ -144,7 +144,7 @@ export class MantleClient implements IMantleClient, IMonitorWithdrawalsClient, I
{ delay: 500, maxTry: 5 },
)
} catch (e) {
this.logger.warning(
this.logger.warn(
`Could not fetch blocks logs. cause: ${e}, startBlock: ${start}, toBlock: ${end}. Total ${end - start}`,
)

Expand Down Expand Up @@ -213,25 +213,40 @@ export class MantleClient implements IMantleClient, IMonitorWithdrawalsClient, I
}

public async getWithdrawalEvents(
fromBlockNumber: number,
toBlockNumber: number,
startBlock: number,
endBlock: number,
): Promise<E.Either<NetworkError, WithdrawalInitiatedEvent[]>> {
try {
const out = await retryAsync<WithdrawalInitiatedEvent[]>(
async (): Promise<WithdrawalInitiatedEvent[]> => {
return await this.L2ERC20TokenBridge.queryFilter(
this.L2ERC20TokenBridge.filters.WithdrawalInitiated(),
fromBlockNumber,
toBlockNumber,
)
},
{ delay: 500, maxTry: 5 },
)
const batchSize = 10_000

return E.right(out)
} catch (e) {
return E.left(new NetworkError(e, `Could not fetch withdrawEvents`))
const events: WithdrawalInitiatedEvent[] = []
for (let i = startBlock; i <= endBlock; i += batchSize) {
const start = i
const end = Math.min(i + batchSize - 1, endBlock)

let chunkEvents: WithdrawalInitiatedEvent[] = []
try {
chunkEvents = await retryAsync<WithdrawalInitiatedEvent[]>(
async (): Promise<WithdrawalInitiatedEvent[]> => {
return await this.L2ERC20TokenBridge.queryFilter(
this.L2ERC20TokenBridge.filters.WithdrawalInitiated(),
start,
end,
)
},
{ delay: 500, maxTry: 5 },
)
} catch (e) {
this.logger.warn(
`Could not fetch withdrawEvents. cause: ${e}, startBlock: ${start}, toBlock: ${end}. Total ${end - start}`,
)

continue
}

events.push(...chunkEvents)
}

return E.right(events)
}

public async getWithdrawalRecords(
Expand Down
90 changes: 90 additions & 0 deletions l2-bridge-mantle/src/clients/proxy_contract_client.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { ProxyContractClient } from './proxy_contract_client'
import { ERC20Short__factory, L2ERC20TokenBridge__factory, OssifiableProxy__factory } from '../generated'
import { Address } from '../utils/constants'
import * as Winston from 'winston'
import { ethers } from 'ethers'
import * as E from 'fp-ts/Either'
import { MantleClient } from './mantle_provider'
import { expect } from '@jest/globals'

const timeout = 120_000

describe('Proxy_watcher tests', () => {
const adr = Address

const logger: Winston.Logger = Winston.createLogger({
format: Winston.format.simple(),
transports: [new Winston.transports.Console()],
})

const mantleRpcURL = 'https://rpc.mantle.xyz'

const baseNetworkID = 5000
const mantleProvider = new ethers.providers.JsonRpcProvider(mantleRpcURL, baseNetworkID)

const l2Bridge = L2ERC20TokenBridge__factory.connect(adr.MANTLE_L2ERC20_TOKEN_BRIDGE_ADDRESS, mantleProvider)
const bridgedWSthEthRunner = ERC20Short__factory.connect(adr.MANTLE_WSTETH_ADDRESS, mantleProvider)
const mantleClient = new MantleClient(mantleProvider, logger, l2Bridge, bridgedWSthEthRunner)

test(
'test MANTLE_L2ERC20_TOKEN_BRIDGED proxy client',
async () => {
const latestL2Block = await mantleClient.getLatestL2Block()
if (E.isLeft(latestL2Block)) {
throw latestL2Block.left
}

const client = new ProxyContractClient(
adr.MANTLE_L2ERC20_TOKEN_BRIDGED.name,
adr.MANTLE_L2ERC20_TOKEN_BRIDGED.address,
OssifiableProxy__factory.connect(adr.MANTLE_L2ERC20_TOKEN_BRIDGED.address, mantleProvider),
)

const proxyImpl = await client.getProxyImplementation(latestL2Block.right.number)
if (E.isLeft(proxyImpl)) {
throw proxyImpl.left
}

expect(proxyImpl.right).toEqual('0xf10A7ffC613a9b23Abc36167925A375bf5986181')

const proxyAdm = await client.getProxyAdmin(latestL2Block.right.number)
if (E.isLeft(proxyAdm)) {
throw proxyAdm.left
}

expect(proxyAdm.right).toEqual('0x3a7B055BF88CdC59D20D0245809C6E6B3c5819dd')
},
timeout,
)

test(
'test MANTLE_WSTETH_BRIDGED proxy client',
async () => {
const latestL2Block = await mantleClient.getLatestL2Block()
if (E.isLeft(latestL2Block)) {
throw latestL2Block.left
}

const client = new ProxyContractClient(
adr.MANTLE_WSTETH_BRIDGED.name,
adr.MANTLE_WSTETH_BRIDGED.address,
OssifiableProxy__factory.connect(adr.MANTLE_WSTETH_BRIDGED.address, mantleProvider),
)

const proxyImpl = await client.getProxyImplementation(latestL2Block.right.number)
if (E.isLeft(proxyImpl)) {
throw proxyImpl.left
}

expect(proxyImpl.right).toEqual('0x1FaBaAec88198291A4efCc85Cabb33a3785165ba')

const proxyAdm = await client.getProxyAdmin(latestL2Block.right.number)
if (E.isLeft(proxyAdm)) {
throw proxyAdm.left
}

expect(proxyAdm.right).toEqual('0x3a7B055BF88CdC59D20D0245809C6E6B3c5819dd')
},
timeout,
)
})
4 changes: 2 additions & 2 deletions l2-bridge-mantle/src/services/monitor_withdrawals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const MAX_WITHDRAWALS_10K_WstEth = 10_000
export type MonitorWithdrawalsInitResp = {
currentWithdrawals: string
}
const HOURS_48 = 60 * 60 * 24 * 2
const AVG_BLOCK_TIME_2SECONDS: number = 2 //s
export const HOURS_48 = 60 * 60 * 24 * 2
export const AVG_BLOCK_TIME_2SECONDS: number = 2 //s

export class MonitorWithdrawals {
private readonly name: string = 'WithdrawalsMonitor'
Expand Down

0 comments on commit deaaefe

Please sign in to comment.