@eth-optimism/sdk
Advanced tools
Comparing version 0.0.0-develop-20240321160336 to 0.0.0-develop-20240322215055
@@ -70,3 +70,4 @@ import { Provider, BlockTag, TransactionResponse, TransactionRequest } from '@ethersproject/abstract-provider'; | ||
getChallengePeriodSeconds(): Promise<number>; | ||
getProvenWithdrawal(withdrawalHash: string): Promise<ProvenWithdrawal>; | ||
getProvenWithdrawal(withdrawalHash: string): Promise<ProvenWithdrawal | null>; | ||
isValidOutputRoot(outputRoot: string, l2BlockNumber: number): Promise<boolean>; | ||
getMessageBedrockOutput(message: MessageLike, messageIndex?: number): Promise<BedrockOutputData | null>; | ||
@@ -73,0 +74,0 @@ getMessageStateRoot(message: MessageLike, messageIndex?: number): Promise<StateRoot | null>; |
@@ -509,7 +509,4 @@ "use strict"; | ||
const withdrawal = await this.toLowLevelMessage(resolved, messageIndex); | ||
const portal = (await this.fpac()) | ||
? this.contracts.l1.OptimismPortal2 | ||
: this.contracts.l1.OptimismPortal; | ||
const provenWithdrawal = await portal.provenWithdrawals((0, utils_1.hashLowLevelMessage)(withdrawal)); | ||
if (provenWithdrawal.timestamp.eq(ethers_1.BigNumber.from(0))) { | ||
const provenWithdrawal = await this.getProvenWithdrawal((0, utils_1.hashLowLevelMessage)(withdrawal)); | ||
if (provenWithdrawal === null) { | ||
return interfaces_1.MessageStatus.READY_TO_PROVE; | ||
@@ -531,10 +528,12 @@ } | ||
const withdrawalHash = (0, utils_1.hashLowLevelMessage)(withdrawal); | ||
const provenWithdrawal = await this.contracts.l1.OptimismPortal2.provenWithdrawals(withdrawalHash); | ||
const game = new ethers_1.ethers.Contract(provenWithdrawal.disputeGameProxy, (0, utils_1.getContractInterfaceBedrock)('FaultDisputeGame'), this.l1SignerOrProvider); | ||
const status = await game.status(); | ||
if (status === 1) { | ||
throw new Error(`withdrawal proposal was invalidated, must reprove`); | ||
const provenWithdrawal = await this.getProvenWithdrawal(withdrawalHash); | ||
if (provenWithdrawal === null) { | ||
console.warn('Unexpected code path reached in getMessageStatus, returning READY_TO_PROVE'); | ||
return interfaces_1.MessageStatus.READY_TO_PROVE; | ||
} | ||
if (!('proofSubmitter' in provenWithdrawal)) { | ||
throw new Error(`expected to get FPAC withdrawal but got legacy withdrawal`); | ||
} | ||
try { | ||
await this.contracts.l1.OptimismPortal2.checkWithdrawal((0, utils_1.hashLowLevelMessage)(withdrawal)); | ||
await this.contracts.l1.OptimismPortal2.checkWithdrawal((0, utils_1.hashLowLevelMessage)(withdrawal), provenWithdrawal.proofSubmitter); | ||
return interfaces_1.MessageStatus.READY_FOR_RELAY; | ||
@@ -714,4 +713,74 @@ } | ||
} | ||
return this.contracts.l1.OptimismPortal.provenWithdrawals(withdrawalHash); | ||
if (!(await this.fpac())) { | ||
const provenWithdrawal = await this.contracts.l1.OptimismPortal.provenWithdrawals(withdrawalHash); | ||
if (provenWithdrawal.timestamp.eq(0)) { | ||
return null; | ||
} | ||
else { | ||
return provenWithdrawal; | ||
} | ||
} | ||
const numProofSubmitters = ethers_1.BigNumber.from(await this.contracts.l1.OptimismPortal2.numProofSubmitters(withdrawalHash)).toNumber(); | ||
for (let i = 0; i < numProofSubmitters; i++) { | ||
const proofSubmitter = await this.contracts.l1.OptimismPortal2.proofSubmitters(withdrawalHash, i); | ||
const provenWithdrawal = await this.contracts.l1.OptimismPortal2.provenWithdrawals(withdrawalHash, proofSubmitter); | ||
const game = new ethers_1.ethers.Contract(provenWithdrawal.disputeGameProxy, (0, utils_1.getContractInterfaceBedrock)('FaultDisputeGame'), this.l1SignerOrProvider); | ||
const status = await game.status(); | ||
if (status === 1) { | ||
continue; | ||
} | ||
else if (status === 2) { | ||
return Object.assign(Object.assign({}, provenWithdrawal), { proofSubmitter }); | ||
} | ||
else if (status > 2) { | ||
throw new Error('got invalid game status'); | ||
} | ||
const extraData = await game.extraData(); | ||
let l2BlockNumber; | ||
try { | ||
; | ||
[l2BlockNumber] = ethers_1.ethers.utils.defaultAbiCoder.decode(['uint256'], extraData); | ||
} | ||
catch (err) { | ||
continue; | ||
} | ||
if (await this.isValidOutputRoot(await game.rootClaim(), l2BlockNumber)) { | ||
return Object.assign(Object.assign({}, provenWithdrawal), { proofSubmitter }); | ||
} | ||
} | ||
return null; | ||
} | ||
async isValidOutputRoot(outputRoot, l2BlockNumber) { | ||
const cached = this._outputCache.find((other) => { | ||
return other.root === outputRoot; | ||
}); | ||
if (cached) { | ||
return cached.valid; | ||
} | ||
if (this._outputCache.length > 10000) { | ||
this._outputCache = this._outputCache.slice(5000); | ||
} | ||
try { | ||
const provider = (0, utils_1.toJsonRpcProvider)(this.l2Provider); | ||
const [block, proof] = await Promise.all([ | ||
provider.send('eth_getBlockByNumber', [ | ||
(0, core_utils_1.toRpcHexString)(l2BlockNumber), | ||
false, | ||
]), | ||
(0, utils_1.makeStateTrieProof)(provider, l2BlockNumber, this.contracts.l2.OVM_L2ToL1MessagePasser.address, ethers_1.ethers.constants.HashZero), | ||
]); | ||
const output = ethers_1.ethers.utils.solidityKeccak256(['bytes32', 'bytes32', 'bytes32', 'bytes32'], [ | ||
ethers_1.ethers.constants.HashZero, | ||
block.stateRoot, | ||
proof.storageRoot, | ||
block.hash, | ||
]); | ||
const valid = output === outputRoot; | ||
this._outputCache.push({ root: outputRoot, valid }); | ||
return valid; | ||
} | ||
catch (err) { | ||
return false; | ||
} | ||
} | ||
async getMessageBedrockOutput(message, messageIndex = 0) { | ||
@@ -746,44 +815,6 @@ const resolved = await this.toCrossChainMessage(message, messageIndex); | ||
for (const option of matches) { | ||
const cached = this._outputCache.find((other) => { | ||
return other.root === option.rootClaim; | ||
}); | ||
if (cached) { | ||
if (cached.valid) { | ||
match = option; | ||
break; | ||
} | ||
else { | ||
continue; | ||
} | ||
if (await this.isValidOutputRoot(option.rootClaim, option.l2BlockNumber)) { | ||
match = option; | ||
break; | ||
} | ||
if (this._outputCache.length > 10000) { | ||
this._outputCache = this._outputCache.slice(5000); | ||
} | ||
try { | ||
const provider = (0, utils_1.toJsonRpcProvider)(this.l2Provider); | ||
const [block, proof] = await Promise.all([ | ||
provider.send('eth_getBlockByNumber', [ | ||
(0, core_utils_1.toRpcHexString)(option.l2BlockNumber), | ||
false, | ||
]), | ||
(0, utils_1.makeStateTrieProof)(provider, option.l2BlockNumber, this.contracts.l2.OVM_L2ToL1MessagePasser.address, ethers_1.ethers.constants.HashZero), | ||
]); | ||
const output = ethers_1.ethers.utils.solidityKeccak256(['bytes32', 'bytes32', 'bytes32', 'bytes32'], [ | ||
ethers_1.ethers.constants.HashZero, | ||
block.stateRoot, | ||
proof.storageRoot, | ||
block.hash, | ||
]); | ||
if (output === option.rootClaim) { | ||
this._outputCache.push({ root: option.rootClaim, valid: true }); | ||
match = option; | ||
break; | ||
} | ||
else { | ||
this._outputCache.push({ root: option.rootClaim, valid: false }); | ||
} | ||
} | ||
catch (err) { | ||
continue; | ||
} | ||
} | ||
@@ -790,0 +821,0 @@ if (!match) { |
@@ -135,3 +135,3 @@ import { Provider, TransactionReceipt, TransactionResponse } from '@ethersproject/abstract-provider'; | ||
} | ||
export interface ProvenWithdrawal { | ||
export interface LegacyProvenWithdrawal { | ||
outputRoot: string; | ||
@@ -141,2 +141,8 @@ timestamp: BigNumber; | ||
} | ||
export interface FPACProvenWithdrawal { | ||
proofSubmitter: string; | ||
disputeGameProxy: string; | ||
timestamp: BigNumber; | ||
} | ||
export type ProvenWithdrawal = LegacyProvenWithdrawal | FPACProvenWithdrawal; | ||
export interface StateRootBatchHeader { | ||
@@ -143,0 +149,0 @@ batchIndex: BigNumber; |
{ | ||
"name": "@eth-optimism/sdk", | ||
"version": "0.0.0-develop-20240321160336", | ||
"version": "0.0.0-develop-20240322215055", | ||
"description": "[Optimism] Tools for working with Optimism", | ||
@@ -5,0 +5,0 @@ "main": "dist/index", |
@@ -261,5 +261,5 @@ import { | ||
/** | ||
* ProvenWithdrawal in OptimismPortal | ||
* ProvenWithdrawal in OptimismPortal. | ||
*/ | ||
export interface ProvenWithdrawal { | ||
export interface LegacyProvenWithdrawal { | ||
outputRoot: string | ||
@@ -271,2 +271,16 @@ timestamp: BigNumber | ||
/** | ||
* ProvenWithdrawal in OptimismPortal (FPAC). | ||
*/ | ||
export interface FPACProvenWithdrawal { | ||
proofSubmitter: string | ||
disputeGameProxy: string | ||
timestamp: BigNumber | ||
} | ||
/** | ||
* ProvenWithdrawal in OptimismPortal (FPAC or Legacy). | ||
*/ | ||
export type ProvenWithdrawal = LegacyProvenWithdrawal | FPACProvenWithdrawal | ||
/** | ||
* Header for a state root batch. | ||
@@ -273,0 +287,0 @@ */ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
419862
8159