Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 44 additions & 21 deletions src/getBatchPosters.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,37 @@ import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';

import { nitroTestnodeL2 } from './chains';
import { sequencerInboxActions } from './decorators/sequencerInboxActions';
import { getInformationFromTestnode, getNitroTestnodePrivateKeyAccounts } from './testHelpers';
import {
getInformationFromTestnode,
getNitroTestnodePrivateKeyAccounts,
PrivateKeyAccountWithPrivateKey,
} from './testHelpers';
import { getBatchPosters } from './getBatchPosters';
import { isAnvilTestMode, getAnvilTestStack } from './integrationTestHelpers/injectedMode';

const env = isAnvilTestMode() ? getAnvilTestStack() : undefined;

let l3RollupOwner: PrivateKeyAccountWithPrivateKey;
let l3Rollup: Address;
let l3UpgradeExecutor: Address;
let l3SequencerInbox: Address;

if (env) {
l3RollupOwner = env.l3.accounts.rollupOwner;
l3Rollup = env.l3.rollup;
l3UpgradeExecutor = env.l3.upgradeExecutor;
l3SequencerInbox = env.l3.sequencerInbox;
} else {
l3RollupOwner = getNitroTestnodePrivateKeyAccounts().l3RollupOwner;

const testNodeInformation = getInformationFromTestnode();
l3Rollup = testNodeInformation.l3Rollup;
l3UpgradeExecutor = testNodeInformation.l3UpgradeExecutor;
l3SequencerInbox = testNodeInformation.l3SequencerInbox;
}

const { l3RollupOwner } = getNitroTestnodePrivateKeyAccounts();
const { l3Rollup, l3UpgradeExecutor, l3SequencerInbox } = getInformationFromTestnode();

const client = createPublicClient({
chain: nitroTestnodeL2,
const l2Client = createPublicClient({
chain: env ? env.l2.chain : nitroTestnodeL2,
transport: http(),
}).extend(
sequencerInboxActions({
Expand All @@ -20,19 +43,19 @@ const client = createPublicClient({
);

async function setBatchPoster(batchPoster: Address, state: boolean) {
const tx = await client.sequencerInboxPrepareTransactionRequest({
const tx = await l2Client.sequencerInboxPrepareTransactionRequest({
functionName: 'setIsBatchPoster',
args: [batchPoster, state],
account: l3RollupOwner.address,
upgradeExecutor: l3UpgradeExecutor,
sequencerInbox: l3SequencerInbox,
});

const txHash = await client.sendRawTransaction({
const txHash = await l2Client.sendRawTransaction({
serializedTransaction: await l3RollupOwner.signTransaction(tx),
});

await client.waitForTransactionReceipt({
await l2Client.waitForTransactionReceipt({
hash: txHash,
});
}
Expand All @@ -43,7 +66,7 @@ describe('successfully get batch posters', () => {
const randomAccount = privateKeyToAccount(generatePrivateKey()).address;

const { isAccurate: isAccurateInitially, batchPosters: initialBatchPosters } =
await getBatchPosters(client, {
await getBatchPosters(l2Client, {
rollup: l3Rollup,
sequencerInbox: l3SequencerInbox,
});
Expand All @@ -56,7 +79,7 @@ describe('successfully get batch posters', () => {
await setBatchPoster(randomAccount, false);

const { isAccurate: isStillAccurate, batchPosters: newBatchPosters } = await getBatchPosters(
client,
l2Client,
{
rollup: l3Rollup,
sequencerInbox: l3SequencerInbox,
Expand All @@ -67,7 +90,7 @@ describe('successfully get batch posters', () => {
expect(isStillAccurate).toBeTruthy();

await setBatchPoster(randomAccount, true);
const { batchPosters, isAccurate } = await getBatchPosters(client, {
const { batchPosters, isAccurate } = await getBatchPosters(l2Client, {
rollup: l3Rollup,
sequencerInbox: l3SequencerInbox,
});
Expand All @@ -78,7 +101,7 @@ describe('successfully get batch posters', () => {
// Reset state for future tests
await setBatchPoster(randomAccount, false);
const { isAccurate: isAccurateFinal, batchPosters: batchPostersFinal } = await getBatchPosters(
client,
l2Client,
{
rollup: l3Rollup,
sequencerInbox: l3SequencerInbox,
Expand All @@ -92,7 +115,7 @@ describe('successfully get batch posters', () => {
const randomAccount = privateKeyToAccount(generatePrivateKey()).address;

const { isAccurate: isAccurateInitially, batchPosters: initialBatchPosters } =
await getBatchPosters(client, {
await getBatchPosters(l2Client, {
rollup: l3Rollup,
sequencerInbox: l3SequencerInbox,
});
Expand All @@ -103,7 +126,7 @@ describe('successfully get batch posters', () => {
await setBatchPoster(randomAccount, true);
await setBatchPoster(randomAccount, true);
const { isAccurate: isStillAccurate, batchPosters: newBatchPosters } = await getBatchPosters(
client,
l2Client,
{
rollup: l3Rollup,
sequencerInbox: l3SequencerInbox,
Expand All @@ -115,7 +138,7 @@ describe('successfully get batch posters', () => {

// Reset state for futures tests
await setBatchPoster(randomAccount, false);
const { batchPosters, isAccurate } = await getBatchPosters(client, {
const { batchPosters, isAccurate } = await getBatchPosters(l2Client, {
rollup: l3Rollup,
sequencerInbox: l3SequencerInbox,
});
Expand All @@ -125,14 +148,14 @@ describe('successfully get batch posters', () => {

it('when adding an existing batch poster', async () => {
const { isAccurate: isAccurateInitially, batchPosters: initialBatchPosters } =
await getBatchPosters(client, { rollup: l3Rollup, sequencerInbox: l3SequencerInbox });
await getBatchPosters(l2Client, { rollup: l3Rollup, sequencerInbox: l3SequencerInbox });
expect(initialBatchPosters).toHaveLength(1);
expect(isAccurateInitially).toBeTruthy();

const firstBatchPoster = initialBatchPosters[0];
await setBatchPoster(firstBatchPoster, true);

const { isAccurate, batchPosters } = await getBatchPosters(client, {
const { isAccurate, batchPosters } = await getBatchPosters(l2Client, {
rollup: l3Rollup,
sequencerInbox: l3SequencerInbox,
});
Expand All @@ -142,13 +165,13 @@ describe('successfully get batch posters', () => {

it('when removing an existing batch poster', async () => {
const { isAccurate: isAccurateInitially, batchPosters: initialBatchPosters } =
await getBatchPosters(client, { rollup: l3Rollup, sequencerInbox: l3SequencerInbox });
await getBatchPosters(l2Client, { rollup: l3Rollup, sequencerInbox: l3SequencerInbox });
expect(initialBatchPosters).toHaveLength(1);
expect(isAccurateInitially).toBeTruthy();

const lastBatchPoster = initialBatchPosters[initialBatchPosters.length - 1];
await setBatchPoster(lastBatchPoster, false);
const { isAccurate, batchPosters } = await getBatchPosters(client, {
const { isAccurate, batchPosters } = await getBatchPosters(l2Client, {
rollup: l3Rollup,
sequencerInbox: l3SequencerInbox,
});
Expand All @@ -157,7 +180,7 @@ describe('successfully get batch posters', () => {

await setBatchPoster(lastBatchPoster, true);
const { isAccurate: isAccurateFinal, batchPosters: batchPostersFinal } = await getBatchPosters(
client,
l2Client,
{ rollup: l3Rollup, sequencerInbox: l3SequencerInbox },
);
expect(batchPostersFinal).toEqual(initialBatchPosters);
Expand Down
81 changes: 69 additions & 12 deletions src/integrationTestHelpers/anvilHarness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
http,
parseEther,
parseGwei,
PublicClient,
Transport,
zeroAddress,
} from 'viem';
import { sepolia } from 'viem/chains';
Expand Down Expand Up @@ -62,7 +64,13 @@ type BaseStack<L2Accounts, L3Accounts> = {
};
l3: {
accounts: L3Accounts;
timingParams: CustomTimingParams;
nativeToken: Address;
rollup: Address;
bridge: Address;
sequencerInbox: Address;
upgradeExecutor: Address;
batchPoster: Address;
};
};

Expand All @@ -71,6 +79,7 @@ export type AnvilTestStack = BaseStack<
deployer: PrivateKeyAccountWithPrivateKey;
},
{
rollupOwner: PrivateKeyAccountWithPrivateKey;
tokenBridgeDeployer: PrivateKeyAccountWithPrivateKey;
}
>;
Expand All @@ -80,6 +89,7 @@ export type InjectedAnvilTestStack = BaseStack<
deployerPrivateKey: Hex;
},
{
rollupOwnerPrivateKey: Hex;
tokenBridgeDeployerPrivateKey: Hex;
}
>;
Expand Down Expand Up @@ -112,6 +122,7 @@ export function dehydrateAnvilTestStack(env: AnvilTestStack): InjectedAnvilTestS
l3: {
...env.l3,
accounts: {
rollupOwnerPrivateKey: env.l3.accounts.rollupOwner.privateKey,
tokenBridgeDeployerPrivateKey: env.l3.accounts.tokenBridgeDeployer.privateKey,
},
},
Expand All @@ -134,6 +145,7 @@ export function hydrateAnvilTestStack(env: InjectedAnvilTestStack): AnvilTestSta
l3: {
...env.l3,
accounts: {
rollupOwner: createAccount(env.l3.accounts.rollupOwnerPrivateKey),
tokenBridgeDeployer: createAccount(env.l3.accounts.tokenBridgeDeployerPrivateKey),
},
},
Expand Down Expand Up @@ -165,14 +177,15 @@ export async function setupAnvilTestStack(): Promise<AnvilTestStack> {
createDockerNetwork(dockerNetworkName);

const l2ChainId = testConstants.DEFAULT_L2_CHAIN_ID;
const l3ChainId = l2ChainId + 1;
const l1RpcPort = testConstants.DEFAULT_L1_RPC_PORT;
const l2RpcPort = testConstants.DEFAULT_L2_RPC_PORT;
const anvilImage = testConstants.DEFAULT_ANVIL_IMAGE;
const nitroImage = testConstants.DEFAULT_NITRO_IMAGE;
const sepoliaBeaconRpc = testConstants.DEFAULT_SEPOLIA_BEACON_RPC;
const anvilForkUrl = testConstants.DEFAULT_SEPOLIA_RPC;
const rollupCreatorVersion: RollupCreatorSupportedVersion = 'v3.2';
const L2TimingParams: CustomTimingParams = {
const rollupTimingParams: CustomTimingParams = {
confirmPeriodBlocks: 150n,
challengeGracePeriodBlocks: 14_400n,
minimumAssertionPeriod: 75n,
Expand Down Expand Up @@ -233,11 +246,11 @@ export async function setupAnvilTestStack(): Promise<AnvilTestStack> {
{
chainId: BigInt(l2ChainId),
owner: harnessDeployer.address,
sequencerInboxMaxTimeVariation: L2TimingParams.sequencerInboxMaxTimeVariation,
confirmPeriodBlocks: L2TimingParams.confirmPeriodBlocks,
challengeGracePeriodBlocks: L2TimingParams.challengeGracePeriodBlocks,
minimumAssertionPeriod: L2TimingParams.minimumAssertionPeriod,
validatorAfkBlocks: L2TimingParams.validatorAfkBlocks,
sequencerInboxMaxTimeVariation: rollupTimingParams.sequencerInboxMaxTimeVariation,
confirmPeriodBlocks: rollupTimingParams.confirmPeriodBlocks,
challengeGracePeriodBlocks: rollupTimingParams.challengeGracePeriodBlocks,
minimumAssertionPeriod: rollupTimingParams.minimumAssertionPeriod,
validatorAfkBlocks: rollupTimingParams.validatorAfkBlocks,
chainConfig: prepareChainConfig({
chainId: l2ChainId,
arbitrum: {
Expand Down Expand Up @@ -338,7 +351,7 @@ export async function setupAnvilTestStack(): Promise<AnvilTestStack> {
});
console.log('Deployer funded on L2');

const l2PublicClient = createPublicClient({
let l2Client: PublicClient<Transport, Chain> = createPublicClient({
chain: l2BootstrapChain,
transport: http(l2RpcUrl),
});
Expand All @@ -356,12 +369,12 @@ export async function setupAnvilTestStack(): Promise<AnvilTestStack> {
});

console.log('Configuring L2 fee settings...');
await configureL2Fees(l2PublicClient, l2WalletClient, harnessDeployer);
await configureL2Fees(l2Client, l2WalletClient, harnessDeployer);
console.log('L2 fee settings updated\n');

console.log('Ensuring L2 create2 factory...');
await ensureCreate2Factory({
publicClient: l2PublicClient,
publicClient: l2Client,
walletClient: l2WalletClient,
fundingAccount: harnessDeployer,
});
Expand Down Expand Up @@ -396,7 +409,7 @@ export async function setupAnvilTestStack(): Promise<AnvilTestStack> {
chainId: l2ChainId,
},
{
publicClient: l2PublicClient,
publicClient: l2Client,
walletClient: blockAdvancerWalletClient,
account: blockAdvancerAccount,
},
Expand Down Expand Up @@ -425,27 +438,71 @@ export async function setupAnvilTestStack(): Promise<AnvilTestStack> {
contracts: {
rollupCreator: { address: l2RollupCreator },
tokenBridgeCreator: { address: harnessDeployer.address },
weth: { address: harnessDeployer.address },
weth: { address: customGasToken.address as Address },
},
});
registerCustomParentChain(l2Chain);
console.log('L1 & L2 chains ready\n');

l2Client = createPublicClient({
chain: l2Chain,
transport: http(l2RpcUrl),
});

console.log('Deploying L3 rollup contracts on L2...');
const l3RollupConfig = createRollupPrepareDeploymentParamsConfig(l2Client, {
chainId: BigInt(l3ChainId),
owner: harnessDeployer.address,
sequencerInboxMaxTimeVariation: rollupTimingParams.sequencerInboxMaxTimeVariation,
confirmPeriodBlocks: rollupTimingParams.confirmPeriodBlocks,
challengeGracePeriodBlocks: rollupTimingParams.challengeGracePeriodBlocks,
minimumAssertionPeriod: rollupTimingParams.minimumAssertionPeriod,
validatorAfkBlocks: rollupTimingParams.validatorAfkBlocks,
chainConfig: prepareChainConfig({
chainId: l3ChainId,
arbitrum: {
InitialChainOwner: harnessDeployer.address,
DataAvailabilityCommittee: true,
},
}),
});

const l3Rollup = await createRollup({
params: {
config: l3RollupConfig,
batchPosters: [harnessDeployer.address],
validators: [harnessDeployer.address],
nativeToken: customGasToken.address as Address,
maxDataSize: 104_857n,
} as CreateRollupParams<'v3.2'>,
account: harnessDeployer,
parentChainPublicClient: l2Client,
rollupCreatorVersion,
});
console.log('L3 rollup contracts deployed on L2\n');

initializedEnv = {
l2: {
rpcUrl: l2RpcUrl,
chain: l2Chain,
accounts: {
deployer: harnessDeployer,
},
timingParams: L2TimingParams,
timingParams: rollupTimingParams,
rollupCreatorVersion,
},
l3: {
accounts: {
rollupOwner: harnessDeployer,
tokenBridgeDeployer: harnessDeployer,
},
timingParams: rollupTimingParams,
nativeToken: customGasToken.address as Address,
rollup: l3Rollup.coreContracts.rollup,
bridge: l3Rollup.coreContracts.bridge,
sequencerInbox: l3Rollup.coreContracts.sequencerInbox,
upgradeExecutor: l3Rollup.coreContracts.upgradeExecutor,
batchPoster: harnessDeployer.address,
},
};

Expand Down
1 change: 1 addition & 0 deletions src/integrationTestHelpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const testConstants = {
DEFAULT_NITRO_IMAGE: 'offchainlabs/nitro-node:v3.9.5-66e42c4',
DEFAULT_NITRO_CONTRACTS_REF: 'v3.2.0-2f747c7',
DEFAULT_L2_CHAIN_ID: 421_337,
DEFAULT_L3_CHAIN_ID: 421_338,
DEFAULT_L1_RPC_PORT: 9645,
DEFAULT_L2_RPC_PORT: 8747,
DEFAULT_SEPOLIA_FORK_BLOCK_NUMBER: 10_490_000,
Expand Down
1 change: 1 addition & 0 deletions vitest.integration.anvil.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default mergeConfig(
include: [
'./src/createRollup.integration.test.ts',
'./src/decorators/arbAggregatorActions.integration.test.ts',
'./src/getBatchPosters.integration.test.ts',
],
fileParallelism: false,
},
Expand Down
Loading