Skip to content

Commit

Permalink
Refactor op-gateway to avoid need for optimism SDK.
Browse files Browse the repository at this point in the history
  • Loading branch information
Arachnid committed Oct 17, 2023
1 parent 1069575 commit 700fa29
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 71 deletions.
Binary file modified bun.lockb
Binary file not shown.
4 changes: 1 addition & 3 deletions op-gateway/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,9 @@
"@chainlink/ccip-read-server": "^0.2.1",
"@commander-js/extra-typings": "^11.0.0",
"@ensdomains/evm-gateway": "^0.1.0",
"@eth-optimism/sdk": "^3.1.4",
"@ethereumjs/block": "^5.0.0",
"@nomicfoundation/ethereumjs-block": "^5.0.2",
"commander": "^11.0.0",
"ethers": "^6.7.1",
"ethers5": "npm:ethers@5"
"ethers": "^6.7.1"
}
}
76 changes: 25 additions & 51 deletions op-gateway/src/OPProofService.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
import { AbiCoder, type AddressLike, JsonRpcProvider } from 'ethers';
import { ethers as ethers5 } from 'ethers5';

import {
asL2Provider,
CrossChainMessenger,
type DeepPartial,
type OEContractsLike,
} from '@eth-optimism/sdk';
import { AbiCoder, type AddressLike, JsonRpcProvider, Contract } from 'ethers';
import { EVMProofHelper, type IProofService } from '@ensdomains/evm-gateway';
import { type JsonRpcBlock } from '@ethereumjs/block';

Expand All @@ -15,52 +7,34 @@ export interface OPProvableBlock {
l2OutputIndex: number;
}

const L2_OUTPUT_ORACLE_ABI = [
'function latestOutputIndex() external view returns (uint256)',
'function getL2Output(uint256 _l2OutputIndex) external view returns (tuple(bytes32 outputRoot, uint128 timestamp, uint128 l2BlockNumber))',
];

const L2_TO_L1_MESSAGE_PASSER_ADDRESS = "0x4200000000000000000000000000000000000016";

/**
* The proofService class can be used to calculate proofs for a given target and slot on the Optimism Bedrock network.
* It's also capable of proofing long types such as mappings or string by using all included slots in the proof.
*
*/
export class OPProofService implements IProofService<OPProvableBlock> {
readonly crossChainMessenger: CrossChainMessenger;
private readonly provider: JsonRpcProvider;
private readonly l2OutputOracle: Contract;
private readonly l2Provider: JsonRpcProvider;
private readonly helper: EVMProofHelper;
private readonly delay: number;

static async create(
l1ProviderUrl: string,
l2ProviderUrl: string,
delay: number,
contracts?: DeepPartial<OEContractsLike>
) {
const provider = new JsonRpcProvider(l2ProviderUrl);
const v5l1Provider = new ethers5.providers.StaticJsonRpcProvider(
l1ProviderUrl
);
const v5l2Provider = new ethers5.providers.StaticJsonRpcProvider(
l2ProviderUrl
);
const opts: ConstructorParameters<typeof CrossChainMessenger>[0] = {
l1ChainId: (await v5l1Provider.getNetwork()).chainId,
l2ChainId: (await v5l2Provider.getNetwork()).chainId,
l1SignerOrProvider: v5l1Provider,
l2SignerOrProvider: asL2Provider(v5l2Provider),
};
if (contracts) {
opts.contracts = contracts;
}
const crossChainMessenger = new CrossChainMessenger(opts);
return new OPProofService(crossChainMessenger, provider, delay);
}

private constructor(
crossChainMessenger: CrossChainMessenger,
provider: JsonRpcProvider,
constructor(
l1Provider: JsonRpcProvider,
l2Provider: JsonRpcProvider,
l2OutputOracleAddress: string,
delay: number
) {
this.crossChainMessenger = crossChainMessenger;
this.provider = provider;
this.helper = new EVMProofHelper(provider);
this.l2Provider = l2Provider;
this.helper = new EVMProofHelper(l2Provider);
this.delay = delay;
this.l2OutputOracle = new Contract(l2OutputOracleAddress, L2_OUTPUT_ORACLE_ABI, l1Provider);
}

/**
Expand All @@ -72,9 +46,9 @@ export class OPProofService implements IProofService<OPProvableBlock> {
* We go a few batches backwards to avoid errors like delays between nodes
*
*/
const l2OutputIndex = (
await this.crossChainMessenger.contracts.l1.L2OutputOracle.latestOutputIndex()
).sub(this.delay);
const l2OutputIndex =
Number(await this.l2OutputOracle.latestOutputIndex()) - this.delay;


/**
* struct OutputProposal {
Expand All @@ -84,13 +58,13 @@ export class OPProofService implements IProofService<OPProvableBlock> {
* }
*/
const outputProposal =
await this.crossChainMessenger.contracts.l1.L2OutputOracle.getL2Output(
await this.l2OutputOracle.getL2Output(
l2OutputIndex
);

return {
number: outputProposal.l2BlockNumber.toNumber(),
l2OutputIndex: l2OutputIndex.toNumber(),
number: outputProposal.l2BlockNumber,
l2OutputIndex: l2OutputIndex,
};
}

Expand Down Expand Up @@ -123,7 +97,7 @@ export class OPProofService implements IProofService<OPProvableBlock> {
slots: bigint[]
): Promise<string> {
const proof = await this.helper.getProofs(block.number, address, slots);
const rpcBlock: JsonRpcBlock = await this.provider.send(
const rpcBlock: JsonRpcBlock = await this.l2Provider.send(
'eth_getBlockByNumber',
['0x' + block.number.toString(16), false]
);
Expand Down Expand Up @@ -156,7 +130,7 @@ export class OPProofService implements IProofService<OPProvableBlock> {
private async getMessagePasserStorageRoot(blockNo: number) {
const { stateRoot } = await this.helper.getProofs(
blockNo,
this.crossChainMessenger.contracts.l2.BedrockMessagePasser.address,
L2_TO_L1_MESSAGE_PASSER_ADDRESS,
[]
);
return stateRoot;
Expand Down
10 changes: 6 additions & 4 deletions op-gateway/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { EVMGateway } from '@ensdomains/evm-gateway';
import { OPProofService, type OPProvableBlock } from './OPProofService.js';
import type { DeepPartial, OEContractsLike } from '@eth-optimism/sdk';
import { JsonRpcProvider } from 'ethers';

export type OPGateway = EVMGateway<OPProvableBlock>;

export async function makeOPGateway(
l1providerUrl: string,
l2providerUrl: string,
delay: number,
contracts?: DeepPartial<OEContractsLike>
l2OutputOracleAddress: string,
delay: number
): Promise<OPGateway> {
const l1Provider = new JsonRpcProvider(l1providerUrl);
const l2Provider = new JsonRpcProvider(l2providerUrl);
return new EVMGateway(
await OPProofService.create(l1providerUrl, l2providerUrl, delay, contracts)
await new OPProofService(l1Provider, l2Provider, l2OutputOracleAddress, delay)
);
}

Expand Down
16 changes: 13 additions & 3 deletions op-gateway/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Command } from '@commander-js/extra-typings';
import { EVMGateway } from '@ensdomains/evm-gateway';
import { OPProofService } from './OPProofService.js';
import { JsonRpcProvider } from 'ethers';

const program = new Command()
.option('-p, --port <port>', 'port to listen on', '8080')
Expand All @@ -14,17 +15,26 @@ const program = new Command()
'l2 provider url',
'http://localhost:9545/'
)
.option(
'-o --l2-output-oracle <address>',
'address for L2 output oracle on the L1',
''
)
.option('-d, --delay <number>', 'number of blocks delay to use', '5');

program.parse();

(async () => {
const options = program.opts();

const l1Provider = new JsonRpcProvider(options.l1ProviderUrl);
const l2Provider = new JsonRpcProvider(options.l2ProviderUrl);

const gateway = new EVMGateway(
await OPProofService.create(
options.l1ProviderUrl,
options.l2ProviderUrl,
new OPProofService(
l1Provider,
l2Provider,
options.l2OutputOracle,
Number(options.delay)
)
);
Expand Down
14 changes: 4 additions & 10 deletions op-verifier/test/testOPVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import {
Provider,
ethers as ethersT,
FetchRequest,
Signer
Signer,
JsonRpcProvider
} from 'ethers';
import express from 'express';
import { ethers } from 'hardhat';
import { EthereumProvider } from 'hardhat/types';
import request from 'supertest';
import fs from 'fs';

type ethersObj = typeof ethersT &
Omit<HardhatEthersHelpers, 'provider'> & {
Expand Down Expand Up @@ -43,18 +43,12 @@ describe('OPVerifier', () => {
signer = await provider.getSigner(0);

const opAddresses = await (await fetch("http://localhost:8080/addresses.json")).json();
opAddresses.StateCommitmentChain = '0x0000000000000000000000000000000000000000';
opAddresses.CanonicalTransactionChain = '0x0000000000000000000000000000000000000000';
opAddresses.BondManager = '0x0000000000000000000000000000000000000000';
opAddresses.L2OutputOracle = opAddresses.L2OutputOracleProxy;

const server = await makeOPGateway(
(hre.network.config as any).url,
(hre.config.networks[hre.network.companionNetworks.l2] as any).url,
5,
{
l1: opAddresses
}
opAddresses.L2OutputOracleProxy,
5,
);
gateway = server.makeApp('/');

Expand Down

0 comments on commit 700fa29

Please sign in to comment.