Skip to content

Commit

Permalink
feat: Add batching options to createRollupFetchTransactionHash
Browse files Browse the repository at this point in the history
closes fs-895
  • Loading branch information
chrstph-dvx committed Oct 8, 2024
1 parent f225ca0 commit 0f2b701
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 74 deletions.
68 changes: 24 additions & 44 deletions src/createRollupFetchTransactionHash.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
import { Address, PublicClient, Transport, Chain } from 'viem';
import { Address, PublicClient, Transport, Chain, GetLogsReturnType } from 'viem';
import { AbiEvent } from 'abitype';

import { getLogsWithBatching } from './utils/getLogsWithBatching';
import { validateParentChain } from './types/ParentChain';
import {
mainnet,
arbitrumOne,
arbitrumNova,
base,
sepolia,
holesky,
arbitrumSepolia,
baseSepolia,
nitroTestnodeL1,
nitroTestnodeL2,
} from './chains';
import { getEarliestRollupCreatorDeploymentBlockNumber } from './utils/getEarliestRollupCreatorDeploymentBlockNumber';

export type CreateRollupFetchTransactionHashParams<TChain extends Chain | undefined> = {
rollup: Address;
publicClient: PublicClient<Transport, TChain>;
batching?: boolean;
};

const RollupInitializedEventAbi: AbiEvent = {
Expand All @@ -40,42 +31,31 @@ const RollupInitializedEventAbi: AbiEvent = {
type: 'event',
};

const earliestRollupCreatorDeploymentBlockNumber = {
// mainnet L1
[mainnet.id]: 18736164n,
// mainnet L2
[arbitrumOne.id]: 150599584n,
[arbitrumNova.id]: 47798739n,
[base.id]: 12978604n,
// testnet L1
[sepolia.id]: 4741823n,
[holesky.id]: 1118493n,
// testnet L2
[arbitrumSepolia.id]: 654628n,
[baseSepolia.id]: 10606961n,
// local nitro-testnode
[nitroTestnodeL1.id]: 0n,
[nitroTestnodeL2.id]: 0n,
};

export async function createRollupFetchTransactionHash<TChain extends Chain | undefined>({
rollup,
publicClient,
batching = false,
}: CreateRollupFetchTransactionHashParams<TChain>) {
const { chainId } = validateParentChain(publicClient);

const fromBlock =
chainId in earliestRollupCreatorDeploymentBlockNumber
? earliestRollupCreatorDeploymentBlockNumber[chainId]
: 'earliest';

// Find the RollupInitialized event from that Rollup contract
const rollupInitializedEvents = await publicClient.getLogs({
address: rollup,
event: RollupInitializedEventAbi,
fromBlock,
toBlock: 'latest',
});
let rollupInitializedEvents: GetLogsReturnType;
if (batching) {
rollupInitializedEvents = await getLogsWithBatching(
publicClient,
{
address: rollup,
event: RollupInitializedEventAbi,
},
{ stopWhenFound: true },
);
} else {
const { chainId } = validateParentChain(publicClient);
rollupInitializedEvents = await publicClient.getLogs({
address: rollup,
event: RollupInitializedEventAbi,
fromBlock: getEarliestRollupCreatorDeploymentBlockNumber(chainId),
toBlock: 'latest',
});
}

if (rollupInitializedEvents.length !== 1) {
throw new Error(
Expand Down
35 changes: 25 additions & 10 deletions src/getBatchPosters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Address,
Chain,
GetLogsReturnType,
Hex,
PublicClient,
Transport,
Expand All @@ -16,6 +17,7 @@ import { upgradeExecutorABI } from './contracts/UpgradeExecutor';
import { gnosisSafeL2ABI } from './contracts/GnosisSafeL2';

import { createRollupFetchTransactionHash } from './createRollupFetchTransactionHash';
import { getLogsWithBatching } from './utils/getLogsWithBatching';

const createRollupABI = getAbiItem({ abi: rollupCreatorABI, name: 'createRollup' });
const createRollupFunctionSelector = getFunctionSelector(createRollupABI);
Expand Down Expand Up @@ -70,6 +72,8 @@ export type GetBatchPostersParams = {
rollup: Address;
/** Address of the sequencerInbox we're getting logs from */
sequencerInbox: Address;
/** Batch the logs query to avoid RPC limiting */
batching?: boolean;
};
export type GetBatchPostersReturnType = {
/**
Expand Down Expand Up @@ -107,30 +111,41 @@ export type GetBatchPostersReturnType = {
*/
export async function getBatchPosters<TChain extends Chain | undefined>(
publicClient: PublicClient<Transport, TChain>,
{ rollup, sequencerInbox }: GetBatchPostersParams,
{ rollup, sequencerInbox, batching = false }: GetBatchPostersParams,
): Promise<GetBatchPostersReturnType> {
let blockNumber: bigint | 'earliest';
let blockNumber: bigint;
let createRollupTransactionHash: Address | null = null;
try {
createRollupTransactionHash = await createRollupFetchTransactionHash({
rollup,
publicClient,
batching,
});
const receipt = await publicClient.waitForTransactionReceipt({
hash: createRollupTransactionHash,
});
blockNumber = receipt.blockNumber;
} catch (e) {
blockNumber = 'earliest';
blockNumber = 0n;
}

const sequencerInboxEvents = await publicClient.getLogs({
address: sequencerInbox,
event: ownerFunctionCalledEventAbi,
args: { id: 1n },
fromBlock: blockNumber,
toBlock: 'latest',
});
let sequencerInboxEvents: GetLogsReturnType<typeof ownerFunctionCalledEventAbi>;
if (batching) {
sequencerInboxEvents = await getLogsWithBatching(publicClient, {
address: sequencerInbox,
event: ownerFunctionCalledEventAbi,
args: { id: 1n },
fromBlock: blockNumber,
});
} else {
sequencerInboxEvents = await publicClient.getLogs({
address: sequencerInbox,
event: ownerFunctionCalledEventAbi,
args: { id: 1n },
fromBlock: blockNumber,
toBlock: 'latest',
});
}

const events = createRollupTransactionHash
? [{ transactionHash: createRollupTransactionHash }, ...sequencerInboxEvents]
Expand Down
36 changes: 26 additions & 10 deletions src/getKeysets.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Address, Chain, Hex, PublicClient, Transport, getAbiItem } from 'viem';
import { Address, Chain, GetLogsReturnType, Hex, PublicClient, Transport, getAbiItem } from 'viem';

import { sequencerInboxABI } from './contracts/SequencerInbox';
import { createRollupFetchTransactionHash } from './createRollupFetchTransactionHash';
import { getLogsWithBatching } from './utils/getLogsWithBatching';

const SetValidKeysetEventAbi = getAbiItem({ abi: sequencerInboxABI, name: 'SetValidKeyset' });
const InvalidateKeysetEventAbi = getAbiItem({ abi: sequencerInboxABI, name: 'InvalidateKeyset' });

export type GetKeysetsParams = {
/** Address of the sequencerInbox we're getting logs from */
sequencerInbox: Address;
/** Batch the logs query to avoid RPC limiting */
batching?: boolean;
};
export type GetKeysetsReturnType = {
/** Map of keyset hash to keyset bytes
Expand All @@ -34,9 +37,9 @@ export type GetKeysetsReturnType = {
*/
export async function getKeysets<TChain extends Chain | undefined>(
publicClient: PublicClient<Transport, TChain>,
{ sequencerInbox }: GetKeysetsParams,
{ sequencerInbox, batching = false }: GetKeysetsParams,
): Promise<GetKeysetsReturnType> {
let blockNumber: bigint | 'earliest';
let blockNumber: bigint;
let createRollupTransactionHash: Address | null = null;
const rollup = await publicClient.readContract({
functionName: 'rollup',
Expand All @@ -47,22 +50,35 @@ export async function getKeysets<TChain extends Chain | undefined>(
createRollupTransactionHash = await createRollupFetchTransactionHash({
rollup,
publicClient,
batching,
});
const receipt = await publicClient.waitForTransactionReceipt({
hash: createRollupTransactionHash,
});
blockNumber = receipt.blockNumber;
} catch (e) {
console.warn(`[getKeysets] ${(e as any).message}`);
blockNumber = 'earliest';
blockNumber = 0n;
}

const events = await publicClient.getLogs({
address: sequencerInbox,
events: [SetValidKeysetEventAbi, InvalidateKeysetEventAbi],
fromBlock: blockNumber,
toBlock: 'latest',
});
let events: GetLogsReturnType<
undefined,
[typeof SetValidKeysetEventAbi, typeof InvalidateKeysetEventAbi]
>;
if (batching) {
events = await getLogsWithBatching(publicClient, {
address: sequencerInbox,
events: [SetValidKeysetEventAbi, InvalidateKeysetEventAbi],
fromBlock: blockNumber,
});
} else {
events = await publicClient.getLogs({
address: sequencerInbox,
events: [SetValidKeysetEventAbi, InvalidateKeysetEventAbi],
fromBlock: blockNumber,
toBlock: 'latest',
});
}

const keysets = events.reduce((acc, event) => {
switch (event.eventName) {
Expand Down
35 changes: 25 additions & 10 deletions src/getValidators.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Address,
Chain,
GetLogsReturnType,
Hex,
PublicClient,
Transport,
Expand All @@ -16,6 +17,7 @@ import { gnosisSafeL2ABI } from './contracts/GnosisSafeL2';
import { rollupABI } from './contracts/Rollup';

import { createRollupFetchTransactionHash } from './createRollupFetchTransactionHash';
import { getLogsWithBatching } from './utils/getLogsWithBatching';

const createRollupABI = getAbiItem({ abi: rollupCreatorABI, name: 'createRollup' });
const createRollupFunctionSelector = getFunctionSelector(createRollupABI);
Expand Down Expand Up @@ -68,6 +70,8 @@ function updateAccumulator(acc: Set<Address>, input: Hex) {
export type GetValidatorsParams = {
/** Address of the rollup we're getting list of validators from */
rollup: Address;
/** Batch the logs query to avoid RPC limiting */
batching?: boolean;
};
export type GetValidatorsReturnType = {
/**
Expand Down Expand Up @@ -102,29 +106,40 @@ export type GetValidatorsReturnType = {
*/
export async function getValidators<TChain extends Chain | undefined>(
publicClient: PublicClient<Transport, TChain>,
{ rollup }: GetValidatorsParams,
{ rollup, batching = false }: GetValidatorsParams,
): Promise<GetValidatorsReturnType> {
let blockNumber: bigint | 'earliest';
let blockNumber: bigint;
try {
const createRollupTransactionHash = await createRollupFetchTransactionHash({
rollup,
publicClient,
batching,
});
const receipt = await publicClient.waitForTransactionReceipt({
hash: createRollupTransactionHash,
});
blockNumber = receipt.blockNumber;
} catch (e) {
blockNumber = 'earliest';
blockNumber = 0n;
}

const events = await publicClient.getLogs({
address: rollup,
event: ownerFunctionCalledEventAbi,
args: { id: 6n },
fromBlock: blockNumber,
toBlock: 'latest',
});
let events: GetLogsReturnType<typeof ownerFunctionCalledEventAbi>;
if (batching) {
events = await getLogsWithBatching(publicClient, {
address: rollup,
event: ownerFunctionCalledEventAbi,
args: { id: 6n },
fromBlock: blockNumber,
});
} else {
events = await publicClient.getLogs({
address: rollup,
event: ownerFunctionCalledEventAbi,
args: { id: 6n },
fromBlock: blockNumber,
toBlock: 'latest',
});
}

const txs = await Promise.all(
events.map((event) =>
Expand Down
3 changes: 3 additions & 0 deletions src/isAnyTrust.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ function parseConfig(config: { chainConfig: string }): boolean {
export async function isAnyTrust<TChain extends Chain | undefined>({
rollup,
publicClient,
batching = false,
}: {
rollup: Address;
publicClient: PublicClient<Transport, TChain>;
batching?: boolean;
}) {
const createRollupTransactionHash = await createRollupFetchTransactionHash({
rollup,
publicClient,
batching,
});

const transaction = await publicClient.getTransaction({
Expand Down
41 changes: 41 additions & 0 deletions src/utils/getEarliestRollupCreatorDeploymentBlockNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
mainnet,
arbitrumOne,
arbitrumNova,
base,
sepolia,
holesky,
arbitrumSepolia,
baseSepolia,
nitroTestnodeL1,
nitroTestnodeL2,
} from '../chains';
import { ParentChainId } from '../types/ParentChain';

const earliestRollupCreatorDeploymentBlockNumber = {
// mainnet L1
[mainnet.id]: 18_736_164n,
// mainnet L2
[arbitrumOne.id]: 150_599_584n,
[arbitrumNova.id]: 47_798_739n,
[base.id]: 12_978_604n,
// testnet L1
[sepolia.id]: 4_741_823n,
[holesky.id]: 1_118_493n,
// testnet L2
[arbitrumSepolia.id]: 654_628n,
[baseSepolia.id]: 10_606_961n,
// local nitro-testnode
[nitroTestnodeL1.id]: 0n,
[nitroTestnodeL2.id]: 0n,
} as const;

export function getEarliestRollupCreatorDeploymentBlockNumber(chainId: ParentChainId) {
for (const key in earliestRollupCreatorDeploymentBlockNumber) {
if (chainId.toString() === key) {
return earliestRollupCreatorDeploymentBlockNumber[chainId];
}
}

return 'latest';
}
Loading

0 comments on commit 0f2b701

Please sign in to comment.