Skip to content

Commit

Permalink
Merge pull request #30 from base-org/jack/ts-filler-local-support
Browse files Browse the repository at this point in the history
update ts-filler to support local chains for proof generation
  • Loading branch information
jackchuma authored Nov 24, 2024
2 parents 97c42f6 + 39907f0 commit e9c2b89
Show file tree
Hide file tree
Showing 12 changed files with 204 additions and 40 deletions.
5 changes: 2 additions & 3 deletions services/ts-filler/scripts/generateProof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@ import ChainService from "../src/chain/chain.service";
import Prover from "../src/prover/prover.service";
import config from "../src/config";
import chains from "../src/chain/chains";
import { SupportedChains } from "../src/common/types/chain";
import ConfigService from "../src/config/config.service";
import { replaceBigInts } from "../src/common/utils/bigIntReplacer";

// Generate and store proof in json file to be used for testing
async function main() {
const activeChains = {
src: chains[config.sourceChain],
l1: chains[SupportedChains.Sepolia],
l1: chains[config.l1],
dst: chains[config.dstChain],
};

if (!activeChains.src) {
throw new Error(`Invalid Source Chain: ${config.sourceChain}`);
}
if (!activeChains.l1) {
throw new Error(`Invalid L1 Chain: ${SupportedChains.Sepolia}`);
throw new Error(`Invalid L1 Chain: ${config.l1}`);
}
if (!activeChains.dst) {
throw new Error(`Invalid Destination Chain: ${Number(config.dstChain)}`);
Expand Down
7 changes: 6 additions & 1 deletion services/ts-filler/src/chain/chain.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export default class ChainService {
return signedBlock.message;
}

async getL1Block(): Promise<Block> {
return await this.activeChains.l1.publicClient.getBlock();
}

async getL2Block(blockNumber?: bigint): Promise<{
l2Block: Block;
sendRoot?: Address;
Expand All @@ -80,6 +84,7 @@ export default class ChainService {
case SupportedChains.ArbitrumSepolia:
return await this.getArbitrumSepoliaBlock();
case SupportedChains.OptimismSepolia:
case SupportedChains.MockOptimism:
if (!blockNumber) {
throw new Error(
"Block number is required for Optimism Sepolia Block retrieval"
Expand Down Expand Up @@ -169,7 +174,7 @@ export default class ChainService {
const [, l2BlockNumber]: [any, bigint] = await exponentialBackoff(
async () => {
return await config.publicClient.readContract({
address: config.contracts.anchorStateRegistry,
address: this.activeChains.dst.l2Oracle,
abi: AnchorStateRegistry,
functionName: "anchors",
args: [0n],
Expand Down
66 changes: 61 additions & 5 deletions services/ts-filler/src/chain/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {
import { createPublicClient, http } from "viem";

import { Provers, type ChainConfig } from "../common/types/chain";
import { chainA } from "../common/chains/chainA";
import { chainB } from "../common/chains/chainB";
import { mockL1 } from "../common/chains/mockL1";

export default {
// Arbitrum Sepolia
Expand Down Expand Up @@ -66,7 +69,6 @@ export default {
contracts: {
l2MessagePasser: "0x4200000000000000000000000000000000000016",
inbox: "0x49E2cDC9e81825B6C718ae8244fe0D5b062F4874",
weth: "0xAd6A7addf807D846A590E76C5830B609F831Ba2E",
},
publicClient: createPublicClient({
chain: optimismSepolia,
Expand All @@ -81,14 +83,68 @@ export default {
rpcUrl: process.env.SEPOLIA_RPC || sepolia.rpcUrls.default.http[0],
l2Oracle: "0x",
l2OracleStorageKey: "0x",
contracts: {
anchorStateRegistry: "0x218CD9489199F321E1177b56385d333c5B598629",
arbRollup: "0xd80810638dbDF9081b72C1B33c65375e807281C8",
},
contracts: {},
publicClient: createPublicClient({
chain: sepolia,
transport: http(process.env.SEPOLIA_RPC),
}),
targetProver: Provers.None,
},
// Mock Base
111111: {
chainId: 111111,
proverContracts: {
ArbitrumProver: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
OPStackProver: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
},
rpcUrl: "http://localhost:8546",
l2Oracle: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
l2OracleStorageKey:
"0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49",
contracts: {
inbox: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
// outbox: "0xD7a5A114A07cC4B5ebd9C5e1cD1136a99fFA3d68",
},
publicClient: createPublicClient({
chain: chainA,
transport: http(),
}),
targetProver: Provers.OPStackProver,
},
// Mock Optimism
111112: {
chainId: 111112,
proverContracts: {
ArbitrumProver: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
OPStackProver: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
},
rpcUrl: "http://localhost:8547",
l2Oracle: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
l2OracleStorageKey:
"0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49",
contracts: {
inbox: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
// outbox: "0xD7a5A114A07cC4B5ebd9C5e1cD1136a99fFA3d68",
l2MessagePasser: "0x4200000000000000000000000000000000000016",
},
publicClient: createPublicClient({
chain: chainB,
transport: http(),
}),
targetProver: Provers.OPStackProver,
},
// Mock L1
31337: {
chainId: 31337,
proverContracts: {},
rpcUrl: "http://localhost:8545",
l2Oracle: "0x",
l2OracleStorageKey: "0x",
contracts: {},
publicClient: createPublicClient({
chain: mockL1,
transport: http(),
}),
targetProver: Provers.None,
},
} as Record<number, ChainConfig>;
20 changes: 20 additions & 0 deletions services/ts-filler/src/common/chains/chainA.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineChain } from "viem";

export const chainA = defineChain({
id: 111111,
name: "Chain A",
nativeCurrency: {
decimals: 18,
name: "Ether",
symbol: "ETH",
},
rpcUrls: {
default: {
http: ["http://localhost:8546"],
},
},
blockExplorers: {
default: { name: "Explorer", url: "" },
},
contracts: {},
});
20 changes: 20 additions & 0 deletions services/ts-filler/src/common/chains/chainB.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineChain } from "viem";

export const chainB = defineChain({
id: 111112,
name: "Chain B",
nativeCurrency: {
decimals: 18,
name: "Ether",
symbol: "ETH",
},
rpcUrls: {
default: {
http: ["http://localhost:8547"],
},
},
blockExplorers: {
default: { name: "Explorer", url: "" },
},
contracts: {},
});
20 changes: 20 additions & 0 deletions services/ts-filler/src/common/chains/mockL1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineChain } from "viem";

export const mockL1 = defineChain({
id: 31337,
name: "Mock L1",
nativeCurrency: {
decimals: 18,
name: "Ether",
symbol: "ETH",
},
rpcUrls: {
default: {
http: ["http://localhost:8545"],
},
},
blockExplorers: {
default: { name: "Explorer", url: "" },
},
contracts: {},
});
16 changes: 15 additions & 1 deletion services/ts-filler/src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,18 @@ export default {
fulfillmentInfoSlot:
"0x43f1016e17bdb0194ec37b77cf476d255de00011d02616ab831d2e2ce63d9ee2",
},
} as { slots: Record<string, Address> };
mockL1StateRootProof: [
"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563",
"0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6",
"0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace",
"0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b",
"0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b",
"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0",
"0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f",
"0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688",
"0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3",
"0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af",
"0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8",
"0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9",
],
} as { slots: Record<string, Address>; mockL1StateRootProof: `0x${string}`[] };
3 changes: 3 additions & 0 deletions services/ts-filler/src/common/types/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export enum SupportedChains {
BaseSepolia = 84532,
OptimismSepolia = 11155420,
Sepolia = 11155111,
MockBase = 111111,
MockOptimism = 111112,
MockL1 = 31337,
}

export type ActiveChains = {
Expand Down
22 changes: 22 additions & 0 deletions services/ts-filler/src/common/utils/deriveBeaconRoot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { sha256, encodePacked } from "viem";

import constants from "../constants";

export default function deriveBeaconRoot(curr: `0x${string}`): `0x${string}` {
let index = 6434;
const types = ["bytes32", "bytes32"];

for (let i = 0; i < constants.mockL1StateRootProof.length; i++) {
const preImage = [constants.mockL1StateRootProof[i], curr];

if ((index & 1) === 0) {
preImage.reverse();
}

curr = sha256(encodePacked(types, preImage));

index >>= 1;
}

return curr;
}
13 changes: 0 additions & 13 deletions services/ts-filler/src/common/utils/deriveDstStorageSlot.ts

This file was deleted.

11 changes: 5 additions & 6 deletions services/ts-filler/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import type { Address } from "viem";
import { SupportedChains } from "./common/types/chain";

export default {
sourceChain: SupportedChains.BaseSepolia,
// dstChain: SupportedChains.OptimismSepolia,
dstChain: SupportedChains.ArbitrumSepolia,
// requestHash:
// "0xe38ad8c9e84178325f28799eb3aaae72551b2eea7920c43d88854edd350719f5" as Address, // opt-sep
sourceChain: SupportedChains.MockBase,
dstChain: SupportedChains.MockOptimism,
l1: SupportedChains.MockL1,
requestHash:
"0x2ac60f23d7c0dea48c6b0383f3f3c4453a0983beb90d45cbee51ba52a4b4b0f9" as Address,
"0x58592484f8021232d1b9b938e1bed204956dc7d0b2f393561d5aab54750f3552" as Address,
devnet: true,
};
41 changes: 30 additions & 11 deletions services/ts-filler/src/prover/prover.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import type {
ArbitrumProofType,
OPStackProofType,
} from "../common/types/proof";
import config from "../config";
import deriveBeaconRoot from "../common/utils/deriveBeaconRoot";

export default class ProverService {
constructor(
Expand All @@ -39,19 +41,34 @@ export default class ProverService {
async generateProof(
requestHash: Address
): Promise<ArbitrumProofType | OPStackProofType> {
const beaconData = await this.chainService.getBeaconRootAndL2Timestamp();
const beaconBlock = await this.chainService.getBeaconBlock(
beaconData.beaconRoot
);
const stateRootInclusion = this.getExecutionStateRootProof(beaconBlock);

const l1BlockNumber = BigInt(beaconBlock.body.executionPayload.blockNumber);
let beaconData: GetBeaconRootAndL2TimestampReturnType;
let l1BlockNumber: bigint;
let stateRootInclusion: StateRootProofReturnType;

if (config.devnet) {
const l1Block = await this.chainService.getL1Block();
l1BlockNumber = l1Block.number as bigint;
stateRootInclusion = {
proof: constants.mockL1StateRootProof,
leaf: l1Block.stateRoot,
};
beaconData = {
beaconRoot: deriveBeaconRoot(l1Block.stateRoot),
timestampForL2BeaconOracle: l1Block.timestamp,
};
} else {
beaconData = await this.chainService.getBeaconRootAndL2Timestamp();
const beaconBlock = await this.chainService.getBeaconBlock(
beaconData.beaconRoot
);
stateRootInclusion = this.getExecutionStateRootProof(beaconBlock);
l1BlockNumber = BigInt(beaconBlock.body.executionPayload.blockNumber);
}

const { l2Block, sendRoot, nodeIndex } = await this.chainService.getL2Block(
l1BlockNumber
);
const l2Slot = this.deriveRIP7755VerifierStorageSlot(requestHash);
// const l2Slot = deriveOpSepoliaWethStorageSlot();

const storageProofOpts = {
l1BlockNumber,
Expand Down Expand Up @@ -95,14 +112,16 @@ export default class ProverService {
this.buildL1Proof(l1BlockNumber, nodeIndex)
),
dstConfig.publicClient.getProof({
// address: dstConfig.contracts.weth,
address: dstConfig.contracts.inbox,
storageKeys: [l2Slot],
blockNumber: l2Block.number,
}),
];

if (dstConfig.chainId === SupportedChains.OptimismSepolia) {
if (
dstConfig.chainId === SupportedChains.OptimismSepolia ||
dstConfig.chainId === SupportedChains.MockOptimism
) {
calls.push(
dstConfig.publicClient.getProof({
address: dstConfig.contracts.l2MessagePasser,
Expand All @@ -124,7 +143,7 @@ export default class ProverService {
nodeIndex?: bigint
): { address: Address; storageKeys: Address[]; blockNumber: bigint } {
const l1Config = this.activeChains.l1;
let address = l1Config.contracts.anchorStateRegistry;
let address = this.activeChains.dst.l2Oracle;
let storageKeys = [constants.slots.anchorStateRegistrySlot];

if (this.activeChains.dst.chainId === SupportedChains.ArbitrumSepolia) {
Expand Down

0 comments on commit e9c2b89

Please sign in to comment.