From 5567f3e2836e5d399f81d4b181379ed9560bed0a Mon Sep 17 00:00:00 2001 From: Doug Lance Date: Wed, 27 Sep 2023 10:24:43 -0400 Subject: [PATCH] chore: renames L1ToL2Message to parentChain/Chain --- src/index.ts | 10 +- src/lib/message/L1ToL2Message.ts | 390 +++++++++++++++++-------------- src/lib/message/L1Transaction.ts | 16 +- 3 files changed, 225 insertions(+), 191 deletions(-) diff --git a/src/index.ts b/src/index.ts index 6ad13a8124..f2f0964774 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,12 +32,12 @@ export { L1TransactionReceipt, } from './lib/message/L1Transaction' export { - L1ToL2MessageStatus, + ParentChainToChainMessageStatus as L1ToL2MessageStatus, EthDepositStatus, - L1ToL2Message, - L1ToL2MessageReader, - L1ToL2MessageReaderClassic, - L1ToL2MessageWriter, + ParentChainToChainMessage as L1ToL2Message, + ParentChainToChainMessageReader as L1ToL2MessageReader, + ParentChainToChainMessageReaderClassic as L1ToL2MessageReaderClassic, + ParentChainToChainMessageWriter as L1ToL2MessageWriter, } from './lib/message/L1ToL2Message' export { L1ToL2MessageGasEstimator } from './lib/message/L1ToL2MessageGasEstimator' export { argSerializerConstructor } from './lib/utils/byte_serialize_params' diff --git a/src/lib/message/L1ToL2Message.ts b/src/lib/message/L1ToL2Message.ts index e0ef44d007..164619b549 100644 --- a/src/lib/message/L1ToL2Message.ts +++ b/src/lib/message/L1ToL2Message.ts @@ -33,33 +33,36 @@ import { } from '../dataEntities/signerOrProvider' import { ArbSdkError } from '../dataEntities/errors' import { ethers, Overrides } from 'ethers' -import { L2TransactionReceipt, RedeemTransaction } from './L2Transaction' +import { + L2TransactionReceipt as ChainTransactionReceipt, + RedeemTransaction, +} from './L2Transaction' import { getChainNetwork } from '../../lib/dataEntities/networks' import { RetryableMessageParams } from '../dataEntities/message' import { getTransactionReceipt, isDefined } from '../utils/lib' import { EventFetcher } from '../utils/eventFetcher' import { ErrorCode, Logger } from '@ethersproject/logger' -export enum L1ToL2MessageStatus { +export enum ParentChainToChainMessageStatus { /** * The retryable ticket has yet to be created */ NOT_YET_CREATED = 1, /** * An attempt was made to create the retryable ticket, but it failed. - * This could be due to not enough submission cost being paid by the L1 transaction + * This could be due to not enough submission cost being paid by the ParentChain transaction */ CREATION_FAILED = 2, /** * The retryable ticket has been created but has not been redeemed. This could be due to the - * auto redeem failing, or if the params (max l2 gas price) * (max l2 gas) = 0 then no auto + * auto redeem failing, or if the params (max chain gas price) * (max chain gas) = 0 then no auto * redeem tx is ever issued. An auto redeem is also never issued for ETH deposits. * A manual redeem is now required. */ - FUNDS_DEPOSITED_ON_L2 = 3, + FUNDS_DEPOSITED_ON_CHAIN = 3, /** * The retryable ticket has been redeemed (either by auto, or manually) and the - * l2 transaction has been executed + * chain transaction has been executed */ REDEEMED = 4, /** @@ -70,11 +73,11 @@ export enum L1ToL2MessageStatus { export enum EthDepositStatus { /** - * ETH is not deposited on L2 yet + * ETH is not deposited on Chain yet */ PENDING = 1, /** - * ETH is deposited successfully on L2 + * ETH is deposited successfully on Chain */ DEPOSITED = 2, } @@ -87,16 +90,19 @@ interface RetryableExistsError extends Error { /** * Conditional type for Signer or Provider. If T is of type Provider - * then L1ToL2MessageReaderOrWriter will be of type L1ToL2MessageReader. - * If T is of type Signer then L1ToL2MessageReaderOrWriter will be of - * type L1ToL2MessageWriter. + * then ParentChainToChainMessageReaderOrWriter will be of type ParentChainToChainMessageReader. + * If T is of type Signer then ParentChainToChainMessageReaderOrWriter will be of + * type ParentChainToChainMessageWriter. */ -export type L1ToL2MessageReaderOrWriter = - T extends Provider ? L1ToL2MessageReader : L1ToL2MessageWriter +export type ParentChainToChainMessageReaderOrWriter< + T extends SignerOrProvider +> = T extends Provider + ? ParentChainToChainMessageReader + : ParentChainToChainMessageWriter -export abstract class L1ToL2Message { +export abstract class ParentChainToChainMessage { /** - * When messages are sent from L1 to L2 a retryable ticket is created on L2. + * When messages are sent from ParentChain to Chain a retryable ticket is created on Chain. * The retryableCreationId can be used to retrieve information about the success or failure of the * creation of the retryable ticket. */ @@ -105,29 +111,29 @@ export abstract class L1ToL2Message { /** * The submit retryable transactions use the typed transaction envelope 2718. * The id of these transactions is the hash of the RLP encoded transaction. - * @param l2ChainId - * @param fromAddress the aliased address that called the L1 inbox as emitted in the bridge event. + * @param chainChainId + * @param fromAddress the aliased address that called the ParentChain inbox as emitted in the bridge event. * @param messageNumber - * @param l1BaseFee + * @param parentChainBaseFee * @param destAddress - * @param l2CallValue - * @param l1Value + * @param chainCallValue + * @param parentChainValue * @param maxSubmissionFee - * @param excessFeeRefundAddress refund address specified in the retryable creation. Note the L1 inbox aliases this address if it is a L1 smart contract. The user is expected to provide this value already aliased when needed. - * @param callValueRefundAddress refund address specified in the retryable creation. Note the L1 inbox aliases this address if it is a L1 smart contract. The user is expected to provide this value already aliased when needed. + * @param excessFeeRefundAddress refund address specified in the retryable creation. Note the ParentChain inbox aliases this address if it is a ParentChain smart contract. The user is expected to provide this value already aliased when needed. + * @param callValueRefundAddress refund address specified in the retryable creation. Note the ParentChain inbox aliases this address if it is a ParentChain smart contract. The user is expected to provide this value already aliased when needed. * @param gasLimit * @param maxFeePerGas * @param data * @returns */ public static calculateSubmitRetryableId( - l2ChainId: number, + chainChainId: number, fromAddress: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, destAddress: string, - l2CallValue: BigNumber, - l1Value: BigNumber, + chainCallValue: BigNumber, + parentChainValue: BigNumber, maxSubmissionFee: BigNumber, excessFeeRefundAddress: string, callValueRefundAddress: string, @@ -139,21 +145,21 @@ export abstract class L1ToL2Message { return ethers.utils.stripZeros(value.toHexString()) } - const chainId = BigNumber.from(l2ChainId) + const chainId = BigNumber.from(chainChainId) const msgNum = BigNumber.from(messageNumber) const fields: any[] = [ formatNumber(chainId), zeroPad(formatNumber(msgNum), 32), fromAddress, - formatNumber(l1BaseFee), + formatNumber(parentChainBaseFee), - formatNumber(l1Value), + formatNumber(parentChainValue), formatNumber(maxFeePerGas), formatNumber(gasLimit), // when destAddress is 0x0, arbos treat that as nil destAddress === ethers.constants.AddressZero ? '0x' : destAddress, - formatNumber(l2CallValue), + formatNumber(chainCallValue), callValueRefundAddress, formatNumber(maxSubmissionFee), excessFeeRefundAddress, @@ -170,36 +176,36 @@ export abstract class L1ToL2Message { } public static fromEventComponents( - l2SignerOrProvider: T, + chainSignerOrProvider: T, chainId: number, sender: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, messageData: RetryableMessageParams - ): L1ToL2MessageReaderOrWriter + ): ParentChainToChainMessageReaderOrWriter public static fromEventComponents( - l2SignerOrProvider: T, + chainSignerOrProvider: T, chainId: number, sender: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, messageData: RetryableMessageParams - ): L1ToL2MessageReader | L1ToL2MessageWriter { - return SignerProviderUtils.isSigner(l2SignerOrProvider) - ? new L1ToL2MessageWriter( - l2SignerOrProvider, + ): ParentChainToChainMessageReader | ParentChainToChainMessageWriter { + return SignerProviderUtils.isSigner(chainSignerOrProvider) + ? new ParentChainToChainMessageWriter( + chainSignerOrProvider, chainId, sender, messageNumber, - l1BaseFee, + parentChainBaseFee, messageData ) - : new L1ToL2MessageReader( - l2SignerOrProvider, + : new ParentChainToChainMessageReader( + chainSignerOrProvider, chainId, sender, messageNumber, - l1BaseFee, + parentChainBaseFee, messageData ) } @@ -208,55 +214,64 @@ export abstract class L1ToL2Message { public readonly chainId: number, public readonly sender: string, public readonly messageNumber: BigNumber, - public readonly l1BaseFee: BigNumber, + public readonly parentChainBaseFee: BigNumber, public readonly messageData: RetryableMessageParams ) { - this.retryableCreationId = L1ToL2Message.calculateSubmitRetryableId( - chainId, - sender, - messageNumber, - l1BaseFee, - messageData.destAddress, - messageData.l2CallValue, - messageData.l1Value, - messageData.maxSubmissionFee, - messageData.excessFeeRefundAddress, - messageData.callValueRefundAddress, - messageData.gasLimit, - messageData.maxFeePerGas, - messageData.data - ) + this.retryableCreationId = + ParentChainToChainMessage.calculateSubmitRetryableId( + chainId, + sender, + messageNumber, + parentChainBaseFee, + messageData.destAddress, + messageData.l2CallValue, + messageData.l1Value, + messageData.maxSubmissionFee, + messageData.excessFeeRefundAddress, + messageData.callValueRefundAddress, + messageData.gasLimit, + messageData.maxFeePerGas, + messageData.data + ) } } /** - * If the status is redeemed an l2TxReceipt is populated. - * For all other statuses l2TxReceipt is not populated + * If the status is redeemed an chainTxReceipt is populated. + * For all other statuses chainTxReceipt is not populated */ -export type L1ToL2MessageWaitResult = - | { status: L1ToL2MessageStatus.REDEEMED; l2TxReceipt: TransactionReceipt } - | { status: Exclude } +export type ParentChainToChainMessageWaitResult = + | { + status: ParentChainToChainMessageStatus.REDEEMED + chainTxReceipt: TransactionReceipt + } + | { + status: Exclude< + ParentChainToChainMessageStatus, + ParentChainToChainMessageStatus.REDEEMED + > + } export type EthDepositMessageWaitResult = { - l2TxReceipt: TransactionReceipt | null + chainTxReceipt: TransactionReceipt | null } -export class L1ToL2MessageReader extends L1ToL2Message { +export class ParentChainToChainMessageReader extends ParentChainToChainMessage { private retryableCreationReceipt: TransactionReceipt | undefined | null public constructor( - public readonly l2Provider: Provider, + public readonly chainProvider: Provider, chainId: number, sender: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, messageData: RetryableMessageParams ) { - super(chainId, sender, messageNumber, l1BaseFee, messageData) + super(chainId, sender, messageNumber, parentChainBaseFee, messageData) } /** * Try to get the receipt for the retryable ticket creation. - * This is the L2 transaction that creates the retryable ticket. + * This is the Chain transaction that creates the retryable ticket. * If confirmations or timeout is provided, this will wait for the ticket to be created * @returns Null if retryable has not been created */ @@ -266,7 +281,7 @@ export class L1ToL2MessageReader extends L1ToL2Message { ): Promise { if (!this.retryableCreationReceipt) { this.retryableCreationReceipt = await getTransactionReceipt( - this.l2Provider, + this.chainProvider, this.retryableCreationId, confirmations, timeout @@ -285,11 +300,11 @@ export class L1ToL2MessageReader extends L1ToL2Message { const creationReceipt = await this.getRetryableCreationReceipt() if (creationReceipt) { - const l2Receipt = new L2TransactionReceipt(creationReceipt) - const redeemEvents = l2Receipt.getRedeemScheduledEvents() + const chainReceipt = new ChainTransactionReceipt(creationReceipt) + const redeemEvents = chainReceipt.getRedeemScheduledEvents() if (redeemEvents.length === 1) { - return await this.l2Provider.getTransactionReceipt( + return await this.chainProvider.getTransactionReceipt( redeemEvents[0].retryTxHash ) } else if (redeemEvents.length > 1) { @@ -303,34 +318,39 @@ export class L1ToL2MessageReader extends L1ToL2Message { } /** - * Receipt for the successful l2 transaction created by this message. + * Receipt for the successful chain transaction created by this message. * @returns TransactionReceipt of the first successful redeem if exists, otherwise the current status of the message. */ - public async getSuccessfulRedeem(): Promise { - const l2Network = await getChainNetwork(this.l2Provider) - const eventFetcher = new EventFetcher(this.l2Provider) + public async getSuccessfulRedeem(): Promise { + const chainNetwork = await getChainNetwork(this.chainProvider) + const eventFetcher = new EventFetcher(this.chainProvider) const creationReceipt = await this.getRetryableCreationReceipt() if (!isDefined(creationReceipt)) { // retryable was never created, or not created yet // therefore it cant have been redeemed or be expired - return { status: L1ToL2MessageStatus.NOT_YET_CREATED } + return { status: ParentChainToChainMessageStatus.NOT_YET_CREATED } } if (creationReceipt.status === 0) { - return { status: L1ToL2MessageStatus.CREATION_FAILED } + return { status: ParentChainToChainMessageStatus.CREATION_FAILED } } // check the auto redeem first to avoid doing costly log queries in the happy case const autoRedeem = await this.getAutoRedeemAttempt() if (autoRedeem && autoRedeem.status === 1) { - return { l2TxReceipt: autoRedeem, status: L1ToL2MessageStatus.REDEEMED } + return { + chainTxReceipt: autoRedeem, + status: ParentChainToChainMessageStatus.REDEEMED, + } } if (await this.retryableExists()) { // the retryable was created and still exists // therefore it cant have been redeemed or be expired - return { status: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 } + return { + status: ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + } } // from this point on we know that the retryable was created but does not exist, @@ -340,10 +360,12 @@ export class L1ToL2MessageReader extends L1ToL2Message { // to do this we need to filter through the whole lifetime of the ticket looking // for relevant redeem scheduled events let increment = 1000 - let fromBlock = await this.l2Provider.getBlock(creationReceipt.blockNumber) - let timeout = fromBlock.timestamp + l2Network.retryableLifetimeSeconds + let fromBlock = await this.chainProvider.getBlock( + creationReceipt.blockNumber + ) + let timeout = fromBlock.timestamp + chainNetwork.retryableLifetimeSeconds const queriedRange: { from: number; to: number }[] = [] - const maxBlock = await this.l2Provider.getBlockNumber() + const maxBlock = await this.chainProvider.getBlockNumber() while (fromBlock.number < maxBlock) { const toBlockNumber = Math.min(fromBlock.number + increment, maxBlock) @@ -363,7 +385,7 @@ export class L1ToL2MessageReader extends L1ToL2Message { const successfulRedeem = ( await Promise.all( redeemEvents.map(e => - this.l2Provider.getTransactionReceipt(e.event.retryTxHash) + this.chainProvider.getTransactionReceipt(e.event.retryTxHash) ) ) ).filter(r => isDefined(r) && r.status === 1) @@ -374,11 +396,11 @@ export class L1ToL2MessageReader extends L1ToL2Message { ) if (successfulRedeem.length == 1) return { - l2TxReceipt: successfulRedeem[0], - status: L1ToL2MessageStatus.REDEEMED, + chainTxReceipt: successfulRedeem[0], + status: ParentChainToChainMessageStatus.REDEEMED, } - const toBlock = await this.l2Provider.getBlock(toBlockNumber) + const toBlock = await this.chainProvider.getBlock(toBlockNumber) if (toBlock.timestamp > timeout) { // Check for LifetimeExtended event while (queriedRange.length > 0) { @@ -418,7 +440,7 @@ export class L1ToL2MessageReader extends L1ToL2Message { // we know from earlier that the retryable no longer exists, so if we havent found the redemption // we know that it must have expired - return { status: L1ToL2MessageStatus.EXPIRED } + return { status: ParentChainToChainMessageStatus.EXPIRED } } /** @@ -432,12 +454,12 @@ export class L1ToL2MessageReader extends L1ToL2Message { private async retryableExists(): Promise { const currentTimestamp = BigNumber.from( - (await this.l2Provider.getBlock('latest')).timestamp + (await this.chainProvider.getBlock('latest')).timestamp ) try { const timeoutTimestamp = await this.getTimeout() // timeoutTimestamp returns the timestamp at which the retryable ticket expires - // it can also return revert if the ticket l2Tx does not exist + // it can also return revert if the ticket chainTx does not exist return currentTimestamp.lte(timeoutTimestamp) } catch (err) { if ( @@ -452,31 +474,31 @@ export class L1ToL2MessageReader extends L1ToL2Message { } } - public async status(): Promise { + public async status(): Promise { return (await this.getSuccessfulRedeem()).status } /** - * Wait for the retryable ticket to be created, for it to be redeemed, and for the l2Tx to be executed. - * Note: The terminal status of a transaction that only does an eth deposit is FUNDS_DEPOSITED_ON_L2 as - * no L2 transaction needs to be executed, however the terminal state of any other transaction is REDEEMED - * which represents that the retryable ticket has been redeemed and the L2 tx has been executed. + * Wait for the retryable ticket to be created, for it to be redeemed, and for the chainTx to be executed. + * Note: The terminal status of a transaction that only does an eth deposit is FUNDS_DEPOSITED_ON_CHAIN as + * no Chain transaction needs to be executed, however the terminal state of any other transaction is REDEEMED + * which represents that the retryable ticket has been redeemed and the Chain tx has been executed. * @param confirmations Amount of confirmations the retryable ticket and the auto redeem receipt should have * @param timeout Amount of time to wait for the retryable ticket to be created - * Defaults to 15 minutes, as by this time all transactions are expected to be included on L2. Throws on timeout. - * @returns The wait result contains a status, and optionally the l2TxReceipt. - * If the status is "REDEEMED" then a l2TxReceipt is also available on the result. - * If the status has any other value then l2TxReceipt is not populated. + * Defaults to 15 minutes, as by this time all transactions are expected to be included on Chain. Throws on timeout. + * @returns The wait result contains a status, and optionally the chainTxReceipt. + * If the status is "REDEEMED" then a chainTxReceipt is also available on the result. + * If the status has any other value then chainTxReceipt is not populated. */ public async waitForStatus( confirmations?: number, timeout?: number - ): Promise { - const l2Network = await getChainNetwork(this.chainId) + ): Promise { + const chainNetwork = await getChainNetwork(this.chainId) const chosenTimeout = isDefined(timeout) ? timeout - : l2Network.depositTimeout + : chainNetwork.depositTimeout // try to wait for the retryable ticket to be created const _retryableCreationReceipt = await this.getRetryableCreationReceipt( @@ -501,10 +523,10 @@ export class L1ToL2MessageReader extends L1ToL2Message { * The minimium lifetime of a retryable tx * @returns */ - public static async getLifetime(l2Provider: Provider): Promise { + public static async getLifetime(chainProvider: Provider): Promise { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - l2Provider + chainProvider ) return await arbRetryableTx.getLifetime() } @@ -516,37 +538,41 @@ export class L1ToL2MessageReader extends L1ToL2Message { public async getTimeout(): Promise { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Provider + this.chainProvider ) return await arbRetryableTx.getTimeout(this.retryableCreationId) } /** - * Address to which CallValue will be credited to on L2 if the retryable ticket times out or is cancelled. + * Address to which CallValue will be credited to on Chain if the retryable ticket times out or is cancelled. * The Beneficiary is also the address with the right to cancel a Retryable Ticket (if the ticket hasn’t been redeemed yet). * @returns */ public getBeneficiary(): Promise { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Provider + this.chainProvider ) return arbRetryableTx.getBeneficiary(this.retryableCreationId) } } -export class L1ToL2MessageReaderClassic { +export class ParentChainToChainMessageReaderClassic { private retryableCreationReceipt: TransactionReceipt | undefined | null public readonly messageNumber: BigNumber public readonly retryableCreationId: string public readonly autoRedeemId: string - public readonly l2TxHash: string - public readonly l2Provider: Provider + public readonly chainTxHash: string + public readonly chainProvider: Provider - constructor(l2Provider: Provider, chainId: number, messageNumber: BigNumber) { + constructor( + chainProvider: Provider, + chainId: number, + messageNumber: BigNumber + ) { const bitFlip = (num: BigNumber) => num.or(BigNumber.from(1).shl(255)) this.messageNumber = messageNumber - this.l2Provider = l2Provider + this.chainProvider = chainProvider this.retryableCreationId = keccak256( concat([ @@ -562,7 +588,7 @@ export class L1ToL2MessageReaderClassic { ]) ) - this.l2TxHash = keccak256( + this.chainTxHash = keccak256( concat([ zeroPad(this.retryableCreationId, 32), zeroPad(BigNumber.from(0).toHexString(), 32), @@ -570,11 +596,11 @@ export class L1ToL2MessageReaderClassic { ) } - private calculateL2DerivedHash(retryableCreationId: string): string { + private calculateChainDerivedHash(retryableCreationId: string): string { return keccak256( concat([ zeroPad(retryableCreationId, 32), - // BN 0 meaning L2 TX + // BN 0 meaning Chain TX zeroPad(BigNumber.from(0).toHexString(), 32), ]) ) @@ -582,7 +608,7 @@ export class L1ToL2MessageReaderClassic { /** * Try to get the receipt for the retryable ticket creation. - * This is the L2 transaction that creates the retryable ticket. + * This is the Chain transaction that creates the retryable ticket. * If confirmations or timeout is provided, this will wait for the ticket to be created * @returns Null if retryable has not been created */ @@ -592,7 +618,7 @@ export class L1ToL2MessageReaderClassic { ): Promise { if (!this.retryableCreationReceipt) { this.retryableCreationReceipt = await getTransactionReceipt( - this.l2Provider, + this.chainProvider, this.retryableCreationId, confirmations, timeout @@ -602,77 +628,81 @@ export class L1ToL2MessageReaderClassic { return this.retryableCreationReceipt || null } - public async status(): Promise { + public async status(): Promise { const creationReceipt = await this.getRetryableCreationReceipt() if (!isDefined(creationReceipt)) { - return L1ToL2MessageStatus.NOT_YET_CREATED + return ParentChainToChainMessageStatus.NOT_YET_CREATED } if (creationReceipt.status === 0) { - return L1ToL2MessageStatus.CREATION_FAILED + return ParentChainToChainMessageStatus.CREATION_FAILED } - const l2DerivedHash = this.calculateL2DerivedHash(this.retryableCreationId) - const l2TxReceipt = await this.l2Provider.getTransactionReceipt( - l2DerivedHash + const chainDerivedHash = this.calculateChainDerivedHash( + this.retryableCreationId + ) + const chainTxReceipt = await this.chainProvider.getTransactionReceipt( + chainDerivedHash ) - if (l2TxReceipt && l2TxReceipt.status === 1) { - return L1ToL2MessageStatus.REDEEMED + if (chainTxReceipt && chainTxReceipt.status === 1) { + return ParentChainToChainMessageStatus.REDEEMED } - return L1ToL2MessageStatus.EXPIRED + return ParentChainToChainMessageStatus.EXPIRED } } -export class L1ToL2MessageWriter extends L1ToL2MessageReader { +export class ParentChainToChainMessageWriter extends ParentChainToChainMessageReader { public constructor( - public readonly l2Signer: Signer, + public readonly chainSigner: Signer, chainId: number, sender: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, messageData: RetryableMessageParams ) { super( - l2Signer.provider!, + chainSigner.provider!, chainId, sender, messageNumber, - l1BaseFee, + parentChainBaseFee, messageData ) - if (!l2Signer.provider) + if (!chainSigner.provider) throw new ArbSdkError('Signer not connected to provider.') } /** * Manually redeem the retryable ticket. - * Throws if message status is not L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 + * Throws if message status is not ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN */ public async redeem(overrides?: Overrides): Promise { const status = await this.status() - if (status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { + if (status === ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Signer + this.chainSigner ) const redeemTx = await arbRetryableTx.redeem(this.retryableCreationId, { ...overrides, }) - return L2TransactionReceipt.toRedeemTransaction( - L2TransactionReceipt.monkeyPatchWait(redeemTx), - this.l2Provider + return ChainTransactionReceipt.toRedeemTransaction( + ChainTransactionReceipt.monkeyPatchWait(redeemTx), + this.chainProvider ) } else { throw new ArbSdkError( `Cannot redeem as retryable does not exist. Message status: ${ - L1ToL2MessageStatus[status] + ParentChainToChainMessageStatus[status] } must be: ${ - L1ToL2MessageStatus[L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2] + ParentChainToChainMessageStatus[ + ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ] }.` ) } @@ -680,22 +710,24 @@ export class L1ToL2MessageWriter extends L1ToL2MessageReader { /** * Cancel the retryable ticket. - * Throws if message status is not L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 + * Throws if message status is not ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN */ public async cancel(overrides?: Overrides): Promise { const status = await this.status() - if (status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { + if (status === ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Signer + this.chainSigner ) return await arbRetryableTx.cancel(this.retryableCreationId, overrides) } else { throw new ArbSdkError( `Cannot cancel as retryable does not exist. Message status: ${ - L1ToL2MessageStatus[status] + ParentChainToChainMessageStatus[status] } must be: ${ - L1ToL2MessageStatus[L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2] + ParentChainToChainMessageStatus[ + ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ] }.` ) } @@ -703,22 +735,24 @@ export class L1ToL2MessageWriter extends L1ToL2MessageReader { /** * Increase the timeout of a retryable ticket. - * Throws if message status is not L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 + * Throws if message status is not ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN */ public async keepAlive(overrides?: Overrides): Promise { const status = await this.status() - if (status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { + if (status === ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Signer + this.chainSigner ) return await arbRetryableTx.keepalive(this.retryableCreationId, overrides) } else { throw new ArbSdkError( `Cannot keep alive as retryable does not exist. Message status: ${ - L1ToL2MessageStatus[status] + ParentChainToChainMessageStatus[status] } must be: ${ - L1ToL2MessageStatus[L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2] + ParentChainToChainMessageStatus[ + ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ] }.` ) } @@ -726,14 +760,14 @@ export class L1ToL2MessageWriter extends L1ToL2MessageReader { } /** - * A message for Eth deposits from L1 to L2 + * A message for Eth deposits from ParentChain to Chain */ export class EthDepositMessage { - public readonly l2DepositTxHash: string - private l2DepositTxReceipt: TransactionReceipt | undefined | null + public readonly chainDepositTxHash: string + private chainDepositTxReceipt: TransactionReceipt | undefined | null public static calculateDepositTxId( - l2ChainId: number, + chainChainId: number, messageNumber: BigNumber, fromAddress: string, toAddress: string, @@ -743,7 +777,7 @@ export class EthDepositMessage { return ethers.utils.stripZeros(numberVal.toHexString()) } - const chainId = BigNumber.from(l2ChainId) + const chainId = BigNumber.from(chainChainId) const msgNum = BigNumber.from(messageNumber) // https://github.com/OffchainLabs/go-ethereum/blob/07e017aa73e32be92aadb52fa327c552e1b7b118/core/types/arb_types.go#L302-L308 @@ -774,7 +808,7 @@ export class EthDepositMessage { to: string value: BigNumber } { - // https://github.com/OffchainLabs/nitro/blob/aa84e899cbc902bf6da753b1d66668a1def2c106/contracts/src/bridge/Inbox.sol#L242 + // https://github.com/OffchainLabs/nitro/blob/aa84e899cbc902bf6da753b1d66668a1def2c106/contracts/src/bridge/Inbox.sol#Chain42 // ethers.defaultAbiCoder doesnt decode packed args, so we do a hardcoded parsing const addressEnd = 2 + 20 * 2 const to = getAddress('0x' + eventData.substring(2, addressEnd)) @@ -785,25 +819,25 @@ export class EthDepositMessage { /** * Create an EthDepositMessage from data emitted in event when calling ethDeposit on Inbox.sol - * @param l2Provider + * @param chainProvider * @param messageNumber The message number in the Inbox.InboxMessageDelivered event * @param senderAddr The sender address from Bridge.MessageDelivered event * @param inboxMessageEventData The data field from the Inbox.InboxMessageDelivered event * @returns */ public static async fromEventComponents( - l2Provider: Provider, + chainProvider: Provider, messageNumber: BigNumber, senderAddr: string, inboxMessageEventData: string ) { - const chainId = (await l2Provider.getNetwork()).chainId + const chainId = (await chainProvider.getNetwork()).chainId const { to, value } = EthDepositMessage.parseEthDepositData( inboxMessageEventData ) return new EthDepositMessage( - l2Provider, + chainProvider, chainId, messageNumber, senderAddr, @@ -814,22 +848,22 @@ export class EthDepositMessage { /** * - * @param l2Provider - * @param l2ChainId + * @param chainProvider + * @param chainChainId * @param messageNumber - * @param to Recipient address of the ETH on L2 + * @param to Recipient address of the ETH on Chain * @param value */ constructor( - private readonly l2Provider: Provider, - public readonly l2ChainId: number, + private readonly chainProvider: Provider, + public readonly chainChainId: number, public readonly messageNumber: BigNumber, public readonly from: string, public readonly to: string, public readonly value: BigNumber ) { - this.l2DepositTxHash = EthDepositMessage.calculateDepositTxId( - l2ChainId, + this.chainDepositTxHash = EthDepositMessage.calculateDepositTxId( + chainChainId, messageNumber, from, to, @@ -838,29 +872,29 @@ export class EthDepositMessage { } public async status(): Promise { - const receipt = await this.l2Provider.getTransactionReceipt( - this.l2DepositTxHash + const receipt = await this.chainProvider.getTransactionReceipt( + this.chainDepositTxHash ) if (receipt === null) return EthDepositStatus.PENDING else return EthDepositStatus.DEPOSITED } public async wait(confirmations?: number, timeout?: number) { - const l2Network = await getChainNetwork(this.l2ChainId) + const chainNetwork = await getChainNetwork(this.chainChainId) const chosenTimeout = isDefined(timeout) ? timeout - : l2Network.depositTimeout + : chainNetwork.depositTimeout - if (!this.l2DepositTxReceipt) { - this.l2DepositTxReceipt = await getTransactionReceipt( - this.l2Provider, - this.l2DepositTxHash, + if (!this.chainDepositTxReceipt) { + this.chainDepositTxReceipt = await getTransactionReceipt( + this.chainProvider, + this.chainDepositTxHash, confirmations, chosenTimeout ) } - return this.l2DepositTxReceipt || null + return this.chainDepositTxReceipt || null } } diff --git a/src/lib/message/L1Transaction.ts b/src/lib/message/L1Transaction.ts index 054428a8ad..2f8d5d4ae0 100644 --- a/src/lib/message/L1Transaction.ts +++ b/src/lib/message/L1Transaction.ts @@ -21,13 +21,13 @@ import { Log, Provider } from '@ethersproject/abstract-provider' import { ContractTransaction } from '@ethersproject/contracts' import { BigNumber } from '@ethersproject/bignumber' import { - L1ToL2Message, - L1ToL2MessageReaderOrWriter, - L1ToL2MessageReader, - L1ToL2MessageReaderClassic, - L1ToL2MessageWriter, - L1ToL2MessageStatus, - L1ToL2MessageWaitResult, + ParentChainToChainMessage as L1ToL2Message, + ParentChainToChainMessageReaderOrWriter as L1ToL2MessageReaderOrWriter, + ParentChainToChainMessageReader as L1ToL2MessageReader, + ParentChainToChainMessageReaderClassic as L1ToL2MessageReaderClassic, + ParentChainToChainMessageWriter as L1ToL2MessageWriter, + ParentChainToChainMessageStatus as L1ToL2MessageStatus, + ParentChainToChainMessageWaitResult as L1ToL2MessageWaitResult, EthDepositMessage, EthDepositMessageWaitResult, } from './L1ToL2Message' @@ -372,7 +372,7 @@ export class L1EthDepositTransactionReceipt extends L1TransactionReceipt { return { complete: isDefined(res), - l2TxReceipt: res, + chainTxReceipt: res, message, } }