Skip to content

Commit

Permalink
Merge branch 'dl/347' into dl/l2l1msgclsc
Browse files Browse the repository at this point in the history
  • Loading branch information
douglance committed Oct 4, 2023
2 parents f69b964 + dae6f37 commit cd901cc
Show file tree
Hide file tree
Showing 11 changed files with 233 additions and 167 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@ethersproject/address": "^5.0.8",
"@ethersproject/bignumber": "^5.1.1",
"@ethersproject/bytes": "^5.0.8",
"async-mutex": "^0.4.0",
"ethers": "^5.1.0"
},
"devDependencies": {
Expand Down
16 changes: 8 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@ export {
L2ContractTransaction,
} from './lib/message/L2Transaction'
export {
ChildToParentChainMessage as L2ToL1Message,
ChildToParentChainMessageWriter as L2ToL1MessageWriter,
ChildToParentChainMessageReader as L2ToL1MessageReader,
ChildToParentMessage as L2ToL1Message,
ChildToParentMessageWriter as L2ToL1MessageWriter,
ChildToParentMessageReader as L2ToL1MessageReader,
} from './lib/message/L2ToL1Message'
export {
L1ContractTransaction,
L1TransactionReceipt,
} from './lib/message/L1Transaction'
export {
ParentChainToChainMessageStatus as L1ToL2MessageStatus,
ParentToChildMessageStatus as L1ToL2MessageStatus,
EthDepositStatus,
ParentChainToChainMessage as L1ToL2Message,
ParentChainToChainMessageReader as L1ToL2MessageReader,
ParentChainToChainMessageReaderClassic as L1ToL2MessageReaderClassic,
ParentChainToChainMessageWriter as L1ToL2MessageWriter,
ParentToChildMessage as L1ToL2Message,
ParentToChildMessageReader as L1ToL2MessageReader,
ParentToChildMessageReaderClassic as L1ToL2MessageReaderClassic,
ParentToChildMessageWriter as L1ToL2MessageWriter,
} from './lib/message/L1ToL2Message'
export { L1ToL2MessageGasEstimator } from './lib/message/L1ToL2MessageGasEstimator'
export { argSerializerConstructor } from './lib/utils/byte_serialize_params'
Expand Down
128 changes: 62 additions & 66 deletions src/lib/message/L1ToL2Message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import { getTransactionReceipt, isDefined } from '../utils/lib'
import { EventFetcher } from '../utils/eventFetcher'
import { ErrorCode, Logger } from '@ethersproject/logger'

export enum ParentChainToChainMessageStatus {
export enum ParentToChildMessageStatus {
/**
* The retryable ticket has yet to be created
*/
Expand Down Expand Up @@ -90,17 +90,14 @@ interface RetryableExistsError extends Error {

/**
* Conditional type for Signer or Provider. If T is of type Provider
* then ParentChainToChainMessageReaderOrWriter<T> will be of type ParentChainToChainMessageReader.
* If T is of type Signer then ParentChainToChainMessageReaderOrWriter<T> will be of
* type ParentChainToChainMessageWriter.
* then ParentToChildMessageReaderOrWriter<T> will be of type ParentToChildMessageReader.
* If T is of type Signer then ParentToChildMessageReaderOrWriter<T> will be of
* type ParentToChildMessageWriter.
*/
export type ParentChainToChainMessageReaderOrWriter<
T extends SignerOrProvider
> = T extends Provider
? ParentChainToChainMessageReader
: ParentChainToChainMessageWriter
export type ParentToChildMessageReaderOrWriter<T extends SignerOrProvider> =
T extends Provider ? ParentToChildMessageReader : ParentToChildMessageWriter

export abstract class ParentChainToChainMessage {
export abstract class ParentToChildMessage {
/**
* 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
Expand Down Expand Up @@ -182,25 +179,25 @@ export abstract class ParentChainToChainMessage {
messageNumber: BigNumber,
parentChainBaseFee: BigNumber,
messageData: RetryableMessageParams
): ParentChainToChainMessageReaderOrWriter<T>
): ParentToChildMessageReaderOrWriter<T>
public static fromEventComponents<T extends SignerOrProvider>(
chainSignerOrProvider: T,
chainId: number,
sender: string,
messageNumber: BigNumber,
parentChainBaseFee: BigNumber,
messageData: RetryableMessageParams
): ParentChainToChainMessageReader | ParentChainToChainMessageWriter {
): ParentToChildMessageReader | ParentToChildMessageWriter {
return SignerProviderUtils.isSigner(chainSignerOrProvider)
? new ParentChainToChainMessageWriter(
? new ParentToChildMessageWriter(
chainSignerOrProvider,
chainId,
sender,
messageNumber,
parentChainBaseFee,
messageData
)
: new ParentChainToChainMessageReader(
: new ParentToChildMessageReader(
chainSignerOrProvider,
chainId,
sender,
Expand All @@ -217,46 +214,45 @@ export abstract class ParentChainToChainMessage {
public readonly parentChainBaseFee: BigNumber,
public readonly messageData: RetryableMessageParams
) {
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
)
this.retryableCreationId = ParentToChildMessage.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 chainTxReceipt is populated.
* For all other statuses chainTxReceipt is not populated
*/
export type ParentChainToChainMessageWaitResult =
export type ParentToChildMessageWaitResult =
| {
status: ParentChainToChainMessageStatus.REDEEMED
status: ParentToChildMessageStatus.REDEEMED
chainTxReceipt: TransactionReceipt
}
| {
status: Exclude<
ParentChainToChainMessageStatus,
ParentChainToChainMessageStatus.REDEEMED
ParentToChildMessageStatus,
ParentToChildMessageStatus.REDEEMED
>
}

export type EthDepositMessageWaitResult = {
chainTxReceipt: TransactionReceipt | null
}

export class ParentChainToChainMessageReader extends ParentChainToChainMessage {
export class ParentToChildMessageReader extends ParentToChildMessage {
private retryableCreationReceipt: TransactionReceipt | undefined | null
public constructor(
public readonly chainProvider: Provider,
Expand Down Expand Up @@ -321,35 +317,35 @@ export class ParentChainToChainMessageReader extends ParentChainToChainMessage {
* 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<ParentChainToChainMessageWaitResult> {
public async getSuccessfulRedeem(): Promise<ParentToChildMessageWaitResult> {
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: ParentChainToChainMessageStatus.NOT_YET_CREATED }
return { status: ParentToChildMessageStatus.NOT_YET_CREATED }
}

if (creationReceipt.status === 0) {
return { status: ParentChainToChainMessageStatus.CREATION_FAILED }
return { status: ParentToChildMessageStatus.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 {
chainTxReceipt: autoRedeem,
status: ParentChainToChainMessageStatus.REDEEMED,
status: ParentToChildMessageStatus.REDEEMED,
}
}

if (await this.retryableExists()) {
// the retryable was created and still exists
// therefore it cant have been redeemed or be expired
return {
status: ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN,
status: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN,
}
}

Expand Down Expand Up @@ -397,7 +393,7 @@ export class ParentChainToChainMessageReader extends ParentChainToChainMessage {
if (successfulRedeem.length == 1)
return {
chainTxReceipt: successfulRedeem[0],
status: ParentChainToChainMessageStatus.REDEEMED,
status: ParentToChildMessageStatus.REDEEMED,
}

const toBlock = await this.chainProvider.getBlock(toBlockNumber)
Expand Down Expand Up @@ -440,7 +436,7 @@ export class ParentChainToChainMessageReader extends ParentChainToChainMessage {

// 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: ParentChainToChainMessageStatus.EXPIRED }
return { status: ParentToChildMessageStatus.EXPIRED }
}

/**
Expand Down Expand Up @@ -474,7 +470,7 @@ export class ParentChainToChainMessageReader extends ParentChainToChainMessage {
}
}

public async status(): Promise<ParentChainToChainMessageStatus> {
public async status(): Promise<ParentToChildMessageStatus> {
return (await this.getSuccessfulRedeem()).status
}

Expand All @@ -493,7 +489,7 @@ export class ParentChainToChainMessageReader extends ParentChainToChainMessage {
public async waitForStatus(
confirmations?: number,
timeout?: number
): Promise<ParentChainToChainMessageWaitResult> {
): Promise<ParentToChildMessageWaitResult> {
const chainNetwork = await getChainNetwork(this.chainId)

const chosenTimeout = isDefined(timeout)
Expand Down Expand Up @@ -557,7 +553,7 @@ export class ParentChainToChainMessageReader extends ParentChainToChainMessage {
}
}

export class ParentChainToChainMessageReaderClassic {
export class ParentToChildMessageReaderClassic {
private retryableCreationReceipt: TransactionReceipt | undefined | null
public readonly messageNumber: BigNumber
public readonly retryableCreationId: string
Expand Down Expand Up @@ -628,15 +624,15 @@ export class ParentChainToChainMessageReaderClassic {
return this.retryableCreationReceipt || null
}

public async status(): Promise<ParentChainToChainMessageStatus> {
public async status(): Promise<ParentToChildMessageStatus> {
const creationReceipt = await this.getRetryableCreationReceipt()

if (!isDefined(creationReceipt)) {
return ParentChainToChainMessageStatus.NOT_YET_CREATED
return ParentToChildMessageStatus.NOT_YET_CREATED
}

if (creationReceipt.status === 0) {
return ParentChainToChainMessageStatus.CREATION_FAILED
return ParentToChildMessageStatus.CREATION_FAILED
}

const chainDerivedHash = this.calculateChainDerivedHash(
Expand All @@ -647,14 +643,14 @@ export class ParentChainToChainMessageReaderClassic {
)

if (chainTxReceipt && chainTxReceipt.status === 1) {
return ParentChainToChainMessageStatus.REDEEMED
return ParentToChildMessageStatus.REDEEMED
}

return ParentChainToChainMessageStatus.EXPIRED
return ParentToChildMessageStatus.EXPIRED
}
}

export class ParentChainToChainMessageWriter extends ParentChainToChainMessageReader {
export class ParentToChildMessageWriter extends ParentToChildMessageReader {
public constructor(
public readonly chainSigner: Signer,
chainId: number,
Expand All @@ -677,11 +673,11 @@ export class ParentChainToChainMessageWriter extends ParentChainToChainMessageRe

/**
* Manually redeem the retryable ticket.
* Throws if message status is not ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
* Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
*/
public async redeem(overrides?: Overrides): Promise<RedeemTransaction> {
const status = await this.status()
if (status === ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) {
if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) {
const arbRetryableTx = ArbRetryableTx__factory.connect(
ARB_RETRYABLE_TX_ADDRESS,
this.chainSigner
Expand All @@ -698,10 +694,10 @@ export class ParentChainToChainMessageWriter extends ParentChainToChainMessageRe
} else {
throw new ArbSdkError(
`Cannot redeem as retryable does not exist. Message status: ${
ParentChainToChainMessageStatus[status]
ParentToChildMessageStatus[status]
} must be: ${
ParentChainToChainMessageStatus[
ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
ParentToChildMessageStatus[
ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
]
}.`
)
Expand All @@ -710,11 +706,11 @@ export class ParentChainToChainMessageWriter extends ParentChainToChainMessageRe

/**
* Cancel the retryable ticket.
* Throws if message status is not ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
* Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
*/
public async cancel(overrides?: Overrides): Promise<ContractTransaction> {
const status = await this.status()
if (status === ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) {
if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) {
const arbRetryableTx = ArbRetryableTx__factory.connect(
ARB_RETRYABLE_TX_ADDRESS,
this.chainSigner
Expand All @@ -723,10 +719,10 @@ export class ParentChainToChainMessageWriter extends ParentChainToChainMessageRe
} else {
throw new ArbSdkError(
`Cannot cancel as retryable does not exist. Message status: ${
ParentChainToChainMessageStatus[status]
ParentToChildMessageStatus[status]
} must be: ${
ParentChainToChainMessageStatus[
ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
ParentToChildMessageStatus[
ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
]
}.`
)
Expand All @@ -735,11 +731,11 @@ export class ParentChainToChainMessageWriter extends ParentChainToChainMessageRe

/**
* Increase the timeout of a retryable ticket.
* Throws if message status is not ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
* Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
*/
public async keepAlive(overrides?: Overrides): Promise<ContractTransaction> {
const status = await this.status()
if (status === ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) {
if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) {
const arbRetryableTx = ArbRetryableTx__factory.connect(
ARB_RETRYABLE_TX_ADDRESS,
this.chainSigner
Expand All @@ -748,10 +744,10 @@ export class ParentChainToChainMessageWriter extends ParentChainToChainMessageRe
} else {
throw new ArbSdkError(
`Cannot keep alive as retryable does not exist. Message status: ${
ParentChainToChainMessageStatus[status]
ParentToChildMessageStatus[status]
} must be: ${
ParentChainToChainMessageStatus[
ParentChainToChainMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
ParentToChildMessageStatus[
ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN
]
}.`
)
Expand Down
14 changes: 7 additions & 7 deletions src/lib/message/L1Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import { Log, Provider } from '@ethersproject/abstract-provider'
import { ContractTransaction } from '@ethersproject/contracts'
import { BigNumber } from '@ethersproject/bignumber'
import {
ParentChainToChainMessage as L1ToL2Message,
ParentChainToChainMessageReaderOrWriter as L1ToL2MessageReaderOrWriter,
ParentChainToChainMessageReader as L1ToL2MessageReader,
ParentChainToChainMessageReaderClassic as L1ToL2MessageReaderClassic,
ParentChainToChainMessageWriter as L1ToL2MessageWriter,
ParentChainToChainMessageStatus as L1ToL2MessageStatus,
ParentChainToChainMessageWaitResult as L1ToL2MessageWaitResult,
ParentToChildMessage as L1ToL2Message,
ParentToChildMessageReaderOrWriter as L1ToL2MessageReaderOrWriter,
ParentToChildMessageReader as L1ToL2MessageReader,
ParentToChildMessageReaderClassic as L1ToL2MessageReaderClassic,
ParentToChildMessageWriter as L1ToL2MessageWriter,
ParentToChildMessageStatus as L1ToL2MessageStatus,
ParentToChildMessageWaitResult as L1ToL2MessageWaitResult,
EthDepositMessage,
EthDepositMessageWaitResult,
} from './L1ToL2Message'
Expand Down
Loading

0 comments on commit cd901cc

Please sign in to comment.