From a6e60e0290fd419b9eb7e0ddd28eb4d5007e1dbd Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Fri, 19 Apr 2024 15:39:44 -0400 Subject: [PATCH 1/2] chore: remove BigNumber from `messageDataParser` --- src/lib/dataEntities/message.ts | 12 ++-- src/lib/message/ParentToChildMessage.ts | 57 ++++++++++--------- src/lib/message/ParentTransaction.ts | 4 +- src/lib/message/messageDataParser.ts | 24 ++++---- tests/unit/messageDataParser.test.ts | 31 +++++----- tests/unit/parentToChildMessageEvents.test.ts | 22 ++++--- tsconfig.json | 2 +- 7 files changed, 72 insertions(+), 80 deletions(-) diff --git a/src/lib/dataEntities/message.ts b/src/lib/dataEntities/message.ts index ca274d9d7a..6a9e2d55d6 100644 --- a/src/lib/dataEntities/message.ts +++ b/src/lib/dataEntities/message.ts @@ -1,5 +1,3 @@ -import { BigNumber } from '@ethersproject/bignumber' - /** * The components of a submit retryable message. Can be parsed from the * events emitted from the Inbox. @@ -12,15 +10,15 @@ export interface RetryableMessageParams { /** * Call value in L2 message */ - l2CallValue: BigNumber + l2CallValue: bigint /** * Value sent at L1 */ - l1Value: BigNumber + l1Value: bigint /** * Max gas deducted from L2 balance to cover base submission fee */ - maxSubmissionFee: BigNumber + maxSubmissionFee: bigint /** * L2 address address to credit (gaslimit x gasprice - execution cost) */ @@ -32,11 +30,11 @@ export interface RetryableMessageParams { /** * Max gas deducted from user's L2 balance to cover L2 execution */ - gasLimit: BigNumber + gasLimit: bigint /** * Gas price for L2 execution */ - maxFeePerGas: BigNumber + maxFeePerGas: bigint /** * Calldata for of the L2 message */ diff --git a/src/lib/message/ParentToChildMessage.ts b/src/lib/message/ParentToChildMessage.ts index dace3146a5..b107abd251 100644 --- a/src/lib/message/ParentToChildMessage.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -115,7 +115,7 @@ export abstract class ParentToChildMessage { /** * The submit retryable transactions use the typed transaction envelope 2718. * The id of these transactions is the hash of the RLP encoded transaction. - * @param chainChainId + * @param childChainId * @param fromAddress the aliased address that called the ParentChain inbox as emitted in the bridge event. * @param messageNumber * @param parentChainBaseFee @@ -131,26 +131,27 @@ export abstract class ParentToChildMessage { * @returns */ public static calculateSubmitRetryableId( - chainChainId: number, + childChainId: number, fromAddress: string, - messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + messageNumber: bigint, + parentChainBaseFee: bigint, destAddress: string, - chainCallValue: BigNumber, - parentChainValue: BigNumber, - maxSubmissionFee: BigNumber, + chainCallValue: bigint, + parentChainValue: bigint, + maxSubmissionFee: bigint, excessFeeRefundAddress: string, callValueRefundAddress: string, - gasLimit: BigNumber, - maxFeePerGas: BigNumber, + gasLimit: bigint, + maxFeePerGas: bigint, data: string ): string { - const formatNumber = (value: BigNumber): Uint8Array => { - return toBeArray(value.toHexString()) + const formatNumber = (value: bigint): Uint8Array => { + const uintArr = toBeArray(value) + return uintArr } - const chainId = BigNumber.from(chainChainId) - const msgNum = BigNumber.from(messageNumber) + const chainId = BigInt(childChainId) + const msgNum = BigInt(messageNumber) const fields: any[] = [ formatNumber(chainId), @@ -181,16 +182,16 @@ export abstract class ParentToChildMessage { chainSignerOrProvider: T, chainId: number, sender: string, - messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + messageNumber: bigint, + parentChainBaseFee: bigint, messageData: RetryableMessageParams ): ParentToChildMessageReaderOrWriter public static fromEventComponents( chainSignerOrProvider: T, chainId: number, sender: string, - messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + messageNumber: bigint, + parentChainBaseFee: bigint, messageData: RetryableMessageParams ): ParentToChildMessageReader | ParentToChildMessageWriter { return SignerProviderUtils.isSigner(chainSignerOrProvider) @@ -215,8 +216,8 @@ export abstract class ParentToChildMessage { protected constructor( public readonly chainId: number, public readonly sender: string, - public readonly messageNumber: BigNumber, - public readonly parentChainBaseFee: BigNumber, + public readonly messageNumber: bigint, + public readonly parentChainBaseFee: bigint, public readonly messageData: RetryableMessageParams ) { this.retryableCreationId = ParentToChildMessage.calculateSubmitRetryableId( @@ -263,8 +264,8 @@ export class ParentToChildMessageReader extends ParentToChildMessage { public readonly chainProvider: Provider, chainId: number, sender: string, - messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + messageNumber: bigint, + parentChainBaseFee: bigint, messageData: RetryableMessageParams ) { super(chainId, sender, messageNumber, parentChainBaseFee, messageData) @@ -658,8 +659,8 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { public readonly chainSigner: Signer, chainId: number, sender: string, - messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + messageNumber: bigint, + parentChainBaseFee: bigint, messageData: RetryableMessageParams ) { super( @@ -766,7 +767,7 @@ export class EthDepositMessage { private chainDepositTxReceipt: TransactionReceipt | undefined | null public static calculateDepositTxId( - chainChainId: number, + childChainId: number, messageNumber: BigNumber, fromAddress: string, toAddress: string, @@ -776,7 +777,7 @@ export class EthDepositMessage { return toBeArray(numberVal.toHexString()) } - const chainId = BigNumber.from(chainChainId) + const chainId = BigNumber.from(childChainId) const msgNum = BigNumber.from(messageNumber) // https://github.com/OffchainLabs/go-ethereum/blob/07e017aa73e32be92aadb52fa327c552e1b7b118/core/types/arb_types.go#L302-L308 @@ -845,21 +846,21 @@ export class EthDepositMessage { /** * * @param chainProvider - * @param chainChainId + * @param childChainId * @param messageNumber * @param to Recipient address of the ETH on Chain * @param value */ constructor( private readonly chainProvider: Provider, - public readonly chainChainId: number, + public readonly childChainId: number, public readonly messageNumber: BigNumber, public readonly from: string, public readonly to: string, public readonly value: BigNumber ) { this.chainDepositTxHash = EthDepositMessage.calculateDepositTxId( - chainChainId, + childChainId, messageNumber, from, to, diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index 2d1a864aff..806d62ace5 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -284,8 +284,8 @@ export class ParentTransactionReceipt implements TransactionReceipt { childSignerOrProvider, BigNumber.from(chainId).toNumber(), mn.bridgeMessageEvent.sender, - mn.inboxMessageEvent.messageNum, - mn.bridgeMessageEvent.baseFeeL1, + BigInt(mn.inboxMessageEvent.messageNum.toHexString()), + BigInt(mn.bridgeMessageEvent.baseFeeL1.toHexString()), inboxMessageData ) }) diff --git a/src/lib/message/messageDataParser.ts b/src/lib/message/messageDataParser.ts index 5626cfdf03..318a7e38e9 100644 --- a/src/lib/message/messageDataParser.ts +++ b/src/lib/message/messageDataParser.ts @@ -1,6 +1,4 @@ -import { getAddress, zeroPadValue } from 'ethers-v6' -import { defaultAbiCoder } from '@ethersproject/abi' -import { BigNumber } from '@ethersproject/bignumber' +import { AbiCoder, getAddress } from 'ethers-v6' export class SubmitRetryableMessageDataParser { /** @@ -11,7 +9,7 @@ export class SubmitRetryableMessageDataParser { */ public parse(eventData: string) { // decode the data field - is been packed so we cant decode the bytes field this way - const parsed = defaultAbiCoder.decode( + const parsed = AbiCoder.defaultAbiCoder().decode( [ 'uint256', // dest 'uint256', // l2 call balue @@ -24,23 +22,25 @@ export class SubmitRetryableMessageDataParser { 'uint256', // data length ], eventData - ) as BigNumber[] + ) - const addressFromBigNumber = (bn: BigNumber) => - getAddress(zeroPadValue(bn.toHexString(), 20)) + const addressFromBigInt = (value: bigint) => { + const hexString = value.toString(16) + const addr = getAddress(hexString) + return addr + } - const destAddress = addressFromBigNumber(parsed[0]) + const destAddress = addressFromBigInt(parsed[0]) const l2CallValue = parsed[1] const l1Value = parsed[2] const maxSubmissionFee = parsed[3] - const excessFeeRefundAddress = addressFromBigNumber(parsed[4]) - const callValueRefundAddress = addressFromBigNumber(parsed[5]) + const excessFeeRefundAddress = addressFromBigInt(parsed[4]) + const callValueRefundAddress = addressFromBigInt(parsed[5]) const gasLimit = parsed[6] const maxFeePerGas = parsed[7] const callDataLength = parsed[8] const data = - '0x' + - eventData.substring(eventData.length - callDataLength.mul(2).toNumber()) + '0x' + eventData.substring(eventData.length - Number(callDataLength) * 2) return { destAddress, diff --git a/tests/unit/messageDataParser.test.ts b/tests/unit/messageDataParser.test.ts index e7ba0a9658..5a7c5d2cd4 100644 --- a/tests/unit/messageDataParser.test.ts +++ b/tests/unit/messageDataParser.test.ts @@ -3,7 +3,6 @@ import { expect } from 'chai' -import { BigNumber } from 'ethers' import { parseEther } from 'ethers-v6' import { SubmitRetryableMessageDataParser } from '../../src/lib/message/messageDataParser' @@ -26,20 +25,17 @@ describe('SubmitRetryableMessageDataParser', () => { expect(res.excessFeeRefundAddress).to.eq( '0x7F869dC59A96e798e759030b3c39398ba584F087' ) - expect(res.gasLimit.eq(BigNumber.from('0x0210f1')), 'incorrect gas limit') - .to.be.true + expect(res.gasLimit === BigInt('0x0210f1'), 'incorrect gas limit').to.be + .true + expect(res.l1Value === BigInt('0x30346f1c785e'), 'incorrect l1 value').to.be + .true + expect(res.l2CallValue === BigInt(0), 'incorrect l2 call value').to.be.true expect( - res.l1Value.eq(BigNumber.from('0x30346f1c785e')), - 'incorrect l1 value' - ).to.be.true - expect(res.l2CallValue.eq(BigNumber.from(0)), 'incorrect l2 call value').to - .be.true - expect( - res.maxFeePerGas.eq(BigNumber.from('0x172c5865')), + res.maxFeePerGas === BigInt('0x172c5865'), 'incorrect max fee per gas' ).to.be.true expect( - res.maxSubmissionFee.eq(BigNumber.from('0x53280cf149')), + res.maxSubmissionFee === BigInt('0x53280cf149'), 'incorrect max submission fee' ).to.be.true }) @@ -63,14 +59,13 @@ describe('SubmitRetryableMessageDataParser', () => { expect(res.excessFeeRefundAddress).to.eq( '0xf71946496600e1e1d47b8A77EB2f109Fd82dc86a' ) - expect(res.gasLimit.eq(BigNumber.from(0)), 'incorrect gas limit').to.be.true - expect(res.l1Value.eq(parseEther('30.01')), 'incorrect l1 value').to.be.true - expect(res.l2CallValue.eq(BigNumber.from(0)), 'incorrect l2 call value').to - .be.true - expect(res.maxFeePerGas.eq(BigNumber.from(0)), 'incorrect max fee per gas') - .to.be.true + expect(res.gasLimit === BigInt(0), 'incorrect gas limit').to.be.true + expect(res.l1Value === parseEther('30.01'), 'incorrect l1 value').to.be.true + expect(res.l2CallValue === BigInt(0), 'incorrect l2 call value').to.be.true + expect(res.maxFeePerGas === BigInt(0), 'incorrect max fee per gas').to.be + .true expect( - res.maxSubmissionFee.eq(BigNumber.from('0x370e285a0c')), + res.maxSubmissionFee === BigInt('0x370e285a0c'), 'incorrect max submission fee' ).to.be.true }) diff --git a/tests/unit/parentToChildMessageEvents.test.ts b/tests/unit/parentToChildMessageEvents.test.ts index a71f707741..3fe0057b11 100644 --- a/tests/unit/parentToChildMessageEvents.test.ts +++ b/tests/unit/parentToChildMessageEvents.test.ts @@ -1,5 +1,5 @@ import { ParentTransactionReceipt } from './../../src/lib/message/ParentTransaction' -import { BigNumber, constants, providers } from 'ethers' +import { constants, providers } from 'ethers' import { JsonRpcProvider } from '@ethersproject/providers' import { expect } from 'chai' @@ -183,12 +183,10 @@ describe('ParentToChildMessage events', () => { expect(msg.sender, 'incorrect sender').to.be.eq( '0xeA3123E9d9911199a6711321d1277285e6d4F3EC' ) + expect(msg.messageNumber === BigInt('0x504c'), 'incorrect message number') + .to.be.true expect( - msg.messageNumber.eq(BigNumber.from('0x504c')), - 'incorrect message number' - ).to.be.true - expect( - msg.parentChainBaseFee.eq(BigNumber.from('0x05e0fc4c58')), + msg.parentChainBaseFee === BigInt('0x05e0fc4c58'), 'incorrect parent chain base fee' ).to.be.true expect( @@ -196,15 +194,15 @@ describe('ParentToChildMessage events', () => { 'incorrect dest address on messageData' ).to.be.eq('0x6c411aD3E74De3E7Bd422b94A27770f5B86C623B') expect( - msg.messageData.l2CallValue.eq(BigNumber.from('0x0853a0d2313c0000')), + msg.messageData.l2CallValue === BigInt('0x0853a0d2313c0000'), 'incorrect child chain call value on messageData' ).to.be.true expect( - msg.messageData.l1Value.eq(BigNumber.from('0x0854e8ab1802ca80')), + msg.messageData.l1Value === BigInt('0x0854e8ab1802ca80'), 'incorrect parent chain value on messageData' ).to.be.true expect( - msg.messageData.maxSubmissionFee.eq(BigNumber.from('0x01270f6740d880')), + msg.messageData.maxSubmissionFee === BigInt('0x01270f6740d880'), 'incorrect max submission fee on messageData' ).to.be.true expect( @@ -216,11 +214,11 @@ describe('ParentToChildMessage events', () => { 'incorrect call value refund address' ).to.be.eq('0xa2e06c19EE14255889f0Ec0cA37f6D0778D06754') expect( - msg.messageData.gasLimit.eq(BigNumber.from('0x01d566')), + msg.messageData.gasLimit === BigInt('0x01d566'), 'incorrect gas limit on messageData' ).to.be.true expect( - msg.messageData.maxFeePerGas.eq(BigNumber.from('0x11e1a300')), + msg.messageData.maxFeePerGas === BigInt('0x11e1a300'), 'incorrect max fee per gas on messageData' ).to.be.true expect(msg.messageData.data, 'incorrect data on messageData').to.be.eq( @@ -319,7 +317,7 @@ describe('ParentToChildMessage events', () => { expect(isClassic, 'incorrect tx type returned by isClassic call').to.be.true expect(status, 'invalid message status').to.be.eq(5) expect( - msg.messageNumber.eq(BigNumber.from('0x064371')), + BigInt(msg.messageNumber.toHexString()) === BigInt('0x064371'), 'incorrect message number' ).to.be.true expect(msg.retryableCreationId, 'incorrect retryable creation id').to.be.eq( diff --git a/tsconfig.json b/tsconfig.json index 3a5901b621..8fba0a8926 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2017", + "target": "ES2020", "module": "commonjs", "declaration": true, "rootDir": "./src", From 82da9ce84a93d11b90d85509a2db0de403d596d2 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:22:03 -0400 Subject: [PATCH 2/2] fix address padding --- src/lib/message/messageDataParser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/message/messageDataParser.ts b/src/lib/message/messageDataParser.ts index 318a7e38e9..c8a596e5c1 100644 --- a/src/lib/message/messageDataParser.ts +++ b/src/lib/message/messageDataParser.ts @@ -1,4 +1,4 @@ -import { AbiCoder, getAddress } from 'ethers-v6' +import { AbiCoder, getAddress, toBeHex } from 'ethers-v6' export class SubmitRetryableMessageDataParser { /** @@ -25,7 +25,7 @@ export class SubmitRetryableMessageDataParser { ) const addressFromBigInt = (value: bigint) => { - const hexString = value.toString(16) + const hexString = toBeHex(value, 20) const addr = getAddress(hexString) return addr }