mirror of
https://github.com/vacp2p/linea-monorepo.git
synced 2026-01-09 04:08:01 -05:00
Remove V5 from e2e + allow multiple runs no deploy (#411)
This commit is contained in:
@@ -8,7 +8,7 @@ export const VERIFIER_SETTER_ROLE = "0x32937fd5162e282df7e9a14a5073a2425321c7966
|
||||
export const MESSAGE_SENT_EVENT_SIGNATURE = "0xe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c";
|
||||
|
||||
export const HASH_ZERO = ethers.ZeroHash;
|
||||
|
||||
export const EMPTY_CONTRACT_CODE = "0x";
|
||||
export const TRANSACTION_CALLDATA_LIMIT = 30_000;
|
||||
|
||||
export const PAUSE_ALL_ROLE = generateKeccak256(["string"], ["PAUSE_ALL_ROLE"], true);
|
||||
|
||||
@@ -3,7 +3,7 @@ import assert from "assert";
|
||||
import { AbstractSigner, BaseContract, BlockTag, TransactionReceipt, TransactionRequest, Wallet, ethers } from "ethers";
|
||||
import path from "path";
|
||||
import { exec } from "child_process";
|
||||
import { L2MessageService, TokenBridge, LineaRollupV5, LineaRollupV6 } from "../typechain";
|
||||
import { L2MessageService, TokenBridge, LineaRollupV6 } from "../typechain";
|
||||
import { PayableOverrides, TypedContractEvent, TypedDeferredTopicFilter, TypedEventLog } from "../typechain/common";
|
||||
import { MessageEvent, SendMessageArgs } from "./types";
|
||||
|
||||
@@ -148,7 +148,7 @@ export async function getBlockByNumberOrBlockTag(rpcUrl: URL, blockTag: BlockTag
|
||||
}
|
||||
|
||||
export async function getEvents<
|
||||
TContract extends LineaRollupV5 | LineaRollupV6 | L2MessageService | TokenBridge,
|
||||
TContract extends LineaRollupV6 | L2MessageService | TokenBridge,
|
||||
TEvent extends TypedContractEvent,
|
||||
>(
|
||||
contract: TContract,
|
||||
@@ -171,7 +171,7 @@ export async function getEvents<
|
||||
}
|
||||
|
||||
export async function waitForEvents<
|
||||
TContract extends LineaRollupV5 | LineaRollupV6 | L2MessageService | TokenBridge,
|
||||
TContract extends LineaRollupV6 | L2MessageService | TokenBridge,
|
||||
TEvent extends TypedContractEvent,
|
||||
>(
|
||||
contract: TContract,
|
||||
@@ -297,7 +297,7 @@ export function getMessageSentEventFromLogs<T extends BaseContract>(
|
||||
});
|
||||
}
|
||||
|
||||
export const sendMessage = async <T extends LineaRollupV5 | L2MessageService>(
|
||||
export const sendMessage = async <T extends LineaRollupV6 | L2MessageService>(
|
||||
signer: AbstractSigner,
|
||||
contract: T,
|
||||
args: SendMessageArgs,
|
||||
|
||||
@@ -4,12 +4,29 @@ import { config } from "../tests-config";
|
||||
import { deployContract } from "../../common/deployments";
|
||||
import { DummyContract__factory, TestContract__factory } from "../../typechain";
|
||||
import { etherToWei, sendTransactionsToGenerateTrafficWithInterval } from "../../common/utils";
|
||||
import { EMPTY_CONTRACT_CODE } from "../../common/constants";
|
||||
|
||||
declare global {
|
||||
var stopL2TrafficGeneration: () => void;
|
||||
}
|
||||
|
||||
export default async (): Promise<void> => {
|
||||
const dummyContractCode = await config.getL1Provider().getCode(config.getL1DummyContractAddress());
|
||||
|
||||
// If this is empty, we have not deployed and prerequisites or configured token bridges.
|
||||
if (dummyContractCode === EMPTY_CONTRACT_CODE) {
|
||||
console.log("Configuring once-off prerequisite contracts");
|
||||
await configureOnceOffPrerequisities();
|
||||
}
|
||||
|
||||
console.log("Generating L2 traffic...");
|
||||
const pollingAccount = await config.getL2AccountManager().generateAccount(etherToWei("200"));
|
||||
const stopPolling = await sendTransactionsToGenerateTrafficWithInterval(pollingAccount, 2_000);
|
||||
|
||||
global.stopL2TrafficGeneration = stopPolling;
|
||||
};
|
||||
|
||||
async function configureOnceOffPrerequisities() {
|
||||
const l1AccountManager = config.getL1AccountManager();
|
||||
const l2AccountManager = config.getL2AccountManager();
|
||||
|
||||
@@ -55,10 +72,4 @@ export default async (): Promise<void> => {
|
||||
console.log(`L1 Dummy contract deployed at address: ${await dummyContract.getAddress()}`);
|
||||
console.log(`L2 Dummy contract deployed at address: ${await l2DummyContract.getAddress()}`);
|
||||
console.log(`L2 Test contract deployed at address: ${await l2TestContract.getAddress()}`);
|
||||
|
||||
console.log("Generating L2 traffic...");
|
||||
const pollingAccount = await config.getL2AccountManager().generateAccount(etherToWei("200"));
|
||||
const stopPolling = await sendTransactionsToGenerateTrafficWithInterval(pollingAccount, 2_000);
|
||||
|
||||
global.stopL2TrafficGeneration = stopPolling;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import {
|
||||
DummyContract__factory,
|
||||
L2MessageService,
|
||||
L2MessageService__factory,
|
||||
LineaRollupV5,
|
||||
LineaRollupV5__factory,
|
||||
LineaRollupV6,
|
||||
LineaRollupV6__factory,
|
||||
ProxyAdmin,
|
||||
ProxyAdmin__factory,
|
||||
TestContract,
|
||||
@@ -81,8 +81,8 @@ export default class TestSetup {
|
||||
return this.config.L2.transactionExclusionEndpoint;
|
||||
}
|
||||
|
||||
public getLineaRollupContract(signer?: AbstractSigner): LineaRollupV5 {
|
||||
const lineaRollup: LineaRollupV5 = LineaRollupV5__factory.connect(
|
||||
public getLineaRollupContract(signer?: AbstractSigner): LineaRollupV6 {
|
||||
const lineaRollup: LineaRollupV6 = LineaRollupV6__factory.connect(
|
||||
this.config.L1.lineaRollupAddress,
|
||||
this.getL1Provider(),
|
||||
);
|
||||
@@ -227,6 +227,10 @@ export default class TestSetup {
|
||||
return this.config.L2.accountManager;
|
||||
}
|
||||
|
||||
public getL1DummyContractAddress(): string {
|
||||
return this.config.L1.dummyContractAddress;
|
||||
}
|
||||
|
||||
private isLocalL2Config(config: L2Config): config is LocalL2Config {
|
||||
return (
|
||||
(config as LocalL2Config).besuNodeRpcUrl !== undefined &&
|
||||
|
||||
@@ -46,49 +46,49 @@ describe("Coordinator restart test suite", () => {
|
||||
const l1Provider = config.getL1Provider();
|
||||
// await for a finalization to happen on L1
|
||||
const [dataSubmittedEventsBeforeRestart, dataFinalizedEventsBeforeRestart] = await Promise.all([
|
||||
waitForEvents(lineaRollup, lineaRollup.filters.DataSubmittedV2(), 0, "latest"),
|
||||
waitForEvents(lineaRollup, lineaRollup.filters.DataFinalized(), 0, "latest"),
|
||||
waitForEvents(lineaRollup, lineaRollup.filters.DataSubmittedV3(), 0, "latest"),
|
||||
waitForEvents(lineaRollup, lineaRollup.filters.DataFinalizedV3(), 0, "latest"),
|
||||
]);
|
||||
|
||||
const lastDataSubmittedEventBeforeRestart = dataSubmittedEventsBeforeRestart.slice(-1)[0];
|
||||
const lastDataFinalizedEventsBeforeRestart = dataFinalizedEventsBeforeRestart.slice(-1)[0];
|
||||
|
||||
// Just some sanity checks
|
||||
// Check that the coordinator has submitted and finalized data before the restart
|
||||
expect(lastDataSubmittedEventBeforeRestart.args.endBlock).toBeGreaterThan(0n);
|
||||
expect(lastDataFinalizedEventsBeforeRestart.args.lastBlockFinalized).toBeGreaterThan(0n);
|
||||
expect(lastDataSubmittedEventBeforeRestart.blockNumber).toBeGreaterThan(0n);
|
||||
expect(lastDataFinalizedEventsBeforeRestart.args.endBlockNumber).toBeGreaterThan(0n);
|
||||
|
||||
await waitForCoordinatorRestart();
|
||||
|
||||
const currentBlockNumberAfterRestart = await l1Provider.getBlockNumber();
|
||||
|
||||
console.log("Waiting for DataSubmittedV2 event after coordinator restart...");
|
||||
const [dataSubmittedV2EventAfterRestart] = await waitForEvents(
|
||||
console.log("Waiting for DataSubmittedV3 event after coordinator restart...");
|
||||
const [dataSubmittedV3EventAfterRestart] = await waitForEvents(
|
||||
lineaRollup,
|
||||
lineaRollup.filters.DataSubmittedV2(),
|
||||
lineaRollup.filters.DataSubmittedV3(),
|
||||
1_000,
|
||||
currentBlockNumberAfterRestart,
|
||||
"latest",
|
||||
async (events) =>
|
||||
events.filter((event) => event.args.startBlock > lastDataSubmittedEventBeforeRestart.args.endBlock),
|
||||
async (events) => events.filter((event) => event.blockNumber > lastDataSubmittedEventBeforeRestart.blockNumber),
|
||||
);
|
||||
console.log(`New DataSubmittedV2 event found: event=${JSON.stringify(dataSubmittedV2EventAfterRestart)}`);
|
||||
console.log(`New DataSubmittedV3 event found: event=${JSON.stringify(dataSubmittedV3EventAfterRestart)}`);
|
||||
|
||||
console.log("Waiting for DataFinalized event after coordinator restart...");
|
||||
const [dataFinalizedEventAfterRestart] = await waitForEvents(
|
||||
lineaRollup,
|
||||
lineaRollup.filters.DataFinalized(),
|
||||
lineaRollup.filters.DataFinalizedV3(),
|
||||
1_000,
|
||||
currentBlockNumberAfterRestart,
|
||||
"latest",
|
||||
async (events) =>
|
||||
events.filter(
|
||||
(event) => event.args.lastBlockFinalized > lastDataFinalizedEventsBeforeRestart.args.lastBlockFinalized,
|
||||
(event) => event.args.endBlockNumber > lastDataFinalizedEventsBeforeRestart.args.endBlockNumber,
|
||||
),
|
||||
);
|
||||
console.log(`New DataFinalized event found: event=${JSON.stringify(dataFinalizedEventAfterRestart)}`);
|
||||
|
||||
expect(dataFinalizedEventAfterRestart.args.lastBlockFinalized).toBeGreaterThan(
|
||||
lastDataFinalizedEventsBeforeRestart.args.lastBlockFinalized,
|
||||
expect(dataFinalizedEventAfterRestart.args.endBlockNumber).toBeGreaterThan(
|
||||
lastDataFinalizedEventsBeforeRestart.args.endBlockNumber,
|
||||
);
|
||||
},
|
||||
150_000,
|
||||
|
||||
@@ -7,19 +7,8 @@ import {
|
||||
wait,
|
||||
getBlockByNumberOrBlockTag,
|
||||
etherToWei,
|
||||
generateRoleAssignments,
|
||||
convertStringToPaddedHexBytes,
|
||||
getEvents,
|
||||
} from "./common/utils";
|
||||
import { config } from "./config/tests-config";
|
||||
import { deployContract } from "./common/deployments";
|
||||
import { LineaRollupV6__factory } from "./typechain";
|
||||
import { getInitializerData, upgradeContractAndCall } from "./common/upgrades";
|
||||
import {
|
||||
LINEA_ROLLUP_PAUSE_TYPES_ROLES,
|
||||
LINEA_ROLLUP_UNPAUSE_TYPES_ROLES,
|
||||
LINEA_ROLLUP_V6_ROLES,
|
||||
} from "./common/constants";
|
||||
|
||||
const l1AccountManager = config.getL1AccountManager();
|
||||
|
||||
@@ -64,11 +53,11 @@ describe("Submission and finalization test suite", () => {
|
||||
return { l1Messages, l1Receipts };
|
||||
};
|
||||
|
||||
describe("Contracts v5", () => {
|
||||
describe("Contracts v6", () => {
|
||||
it.concurrent(
|
||||
"Check L2 anchoring",
|
||||
async () => {
|
||||
const lineaRollup = config.getLineaRollupContract();
|
||||
const lineaRollupV6 = config.getLineaRollupContract();
|
||||
const l2MessageService = config.getL2MessageServiceContract();
|
||||
|
||||
const { l1Messages } = await sendMessages();
|
||||
@@ -87,7 +76,7 @@ describe("Submission and finalization test suite", () => {
|
||||
);
|
||||
|
||||
const [lastNewMessageRollingHash, lastAnchoredL1MessageNumber] = await Promise.all([
|
||||
lineaRollup.rollingHashes(rollingHashUpdatedEvent.args.messageNumber),
|
||||
lineaRollupV6.rollingHashes(rollingHashUpdatedEvent.args.messageNumber),
|
||||
l2MessageService.lastAnchoredL1MessageNumber(),
|
||||
]);
|
||||
expect(lastNewMessageRollingHash).toEqual(rollingHashUpdatedEvent.args.rollingHash);
|
||||
@@ -101,37 +90,27 @@ describe("Submission and finalization test suite", () => {
|
||||
it.concurrent(
|
||||
"Check L1 data submission and finalization",
|
||||
async () => {
|
||||
const lineaRollup = config.getLineaRollupContract();
|
||||
const lineaRollupV6 = config.getLineaRollupContract();
|
||||
|
||||
const [currentL2BlockNumber, startingRootHash] = await Promise.all([
|
||||
lineaRollup.currentL2BlockNumber(),
|
||||
lineaRollup.stateRootHashes(await lineaRollup.currentL2BlockNumber()),
|
||||
]);
|
||||
const currentL2BlockNumber = await lineaRollupV6.currentL2BlockNumber();
|
||||
|
||||
console.log("Waiting for data submission used to finalize with proof...");
|
||||
// Waiting for data submission starting from migration block number
|
||||
await waitForEvents(
|
||||
lineaRollup,
|
||||
lineaRollup.filters.DataSubmittedV2(undefined, currentL2BlockNumber + 1n),
|
||||
1_000,
|
||||
);
|
||||
console.log("Waiting for DataSubmittedV3 used to finalize with proof...");
|
||||
await waitForEvents(lineaRollupV6, lineaRollupV6.filters.DataSubmittedV3(), 1_000);
|
||||
|
||||
console.log("Waiting for the first DataFinalized event with proof...");
|
||||
// Waiting for first DataFinalized event with proof
|
||||
console.log("Waiting for the first DataFinalizedV3 event with proof...");
|
||||
const [dataFinalizedEvent] = await waitForEvents(
|
||||
lineaRollup,
|
||||
lineaRollup.filters.DataFinalized(undefined, startingRootHash),
|
||||
lineaRollupV6,
|
||||
lineaRollupV6.filters.DataFinalizedV3(currentL2BlockNumber + 1n),
|
||||
1_000,
|
||||
);
|
||||
|
||||
const [lastBlockFinalized, newStateRootHash] = await Promise.all([
|
||||
lineaRollup.currentL2BlockNumber(),
|
||||
lineaRollup.stateRootHashes(dataFinalizedEvent.args.lastBlockFinalized),
|
||||
lineaRollupV6.currentL2BlockNumber(),
|
||||
lineaRollupV6.stateRootHashes(dataFinalizedEvent.args.endBlockNumber),
|
||||
]);
|
||||
|
||||
expect(lastBlockFinalized).toBeGreaterThanOrEqual(dataFinalizedEvent.args.lastBlockFinalized);
|
||||
expect(newStateRootHash).toEqual(dataFinalizedEvent.args.finalRootHash);
|
||||
expect(dataFinalizedEvent.args.withProof).toBeTruthy();
|
||||
expect(lastBlockFinalized).toBeGreaterThanOrEqual(dataFinalizedEvent.args.endBlockNumber);
|
||||
expect(newStateRootHash).toEqual(dataFinalizedEvent.args.finalStateRootHash);
|
||||
|
||||
console.log("Finalization with proof done.");
|
||||
},
|
||||
@@ -173,108 +152,4 @@ describe("Submission and finalization test suite", () => {
|
||||
150_000,
|
||||
);
|
||||
});
|
||||
|
||||
describe("LineaRollup v6 upgrade", () => {
|
||||
// note: we cannot move the chain forward by 6 months, so in theory, this could be any address for e2e test purposes
|
||||
const fallbackoperatorAddress = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
||||
|
||||
beforeAll(async () => {
|
||||
const l1DeployerAccount = l1AccountManager.whaleAccount(0);
|
||||
const l1SecurityCouncil = l1AccountManager.whaleAccount(3);
|
||||
const l1Provider = config.getL1Provider();
|
||||
const proxyAdmin = config.getLineaRollupProxyAdminContract(l1DeployerAccount);
|
||||
|
||||
console.log("Deploying LineaRollup v6 implementation contract...");
|
||||
const { maxFeePerGas, maxPriorityFeePerGas } = await l1Provider.getFeeData();
|
||||
|
||||
const lineaRollupV6Implementation = await deployContract(new LineaRollupV6__factory(), l1DeployerAccount, [
|
||||
{ maxPriorityFeePerGas, maxFeePerGas },
|
||||
]);
|
||||
|
||||
console.log("Upgrading LineaRollup contract to V6...");
|
||||
const newRoleAddresses = generateRoleAssignments(LINEA_ROLLUP_V6_ROLES, await l1SecurityCouncil.getAddress(), []);
|
||||
|
||||
const initializerData = getInitializerData(
|
||||
LineaRollupV6__factory.createInterface(),
|
||||
"reinitializeLineaRollupV6",
|
||||
[newRoleAddresses, LINEA_ROLLUP_PAUSE_TYPES_ROLES, LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, fallbackoperatorAddress],
|
||||
);
|
||||
|
||||
await upgradeContractAndCall(
|
||||
l1DeployerAccount,
|
||||
await proxyAdmin.getAddress(),
|
||||
await config.getLineaRollupContract().getAddress(),
|
||||
await lineaRollupV6Implementation.getAddress(),
|
||||
initializerData,
|
||||
);
|
||||
});
|
||||
|
||||
it("Check LineaRollupVersionChanged and FallbackOperatorAddressSet events are emitted", async () => {
|
||||
const lineaRollupAddress = await config.getLineaRollupContract().getAddress();
|
||||
const lineaRollupV6 = LineaRollupV6__factory.connect(lineaRollupAddress, config.getL1Provider());
|
||||
|
||||
console.log("Waiting for FallbackOperatorAddressSet event...");
|
||||
await waitForEvents(
|
||||
lineaRollupV6,
|
||||
lineaRollupV6.filters.FallbackOperatorAddressSet(undefined, fallbackoperatorAddress),
|
||||
1_000,
|
||||
);
|
||||
|
||||
console.log("Waiting for LineaRollupVersionChanged event...");
|
||||
const expectedVersion5Bytes8 = convertStringToPaddedHexBytes("5.0", 8);
|
||||
const expectedVersion6Bytes8 = convertStringToPaddedHexBytes("6.0", 8);
|
||||
await waitForEvents(
|
||||
lineaRollupV6,
|
||||
lineaRollupV6.filters.LineaRollupVersionChanged(expectedVersion5Bytes8, expectedVersion6Bytes8),
|
||||
1_000,
|
||||
);
|
||||
});
|
||||
|
||||
it("Check all new roles have been granted and pauseTypes/unpauseTypes are assigned to specific roles", async () => {
|
||||
const lineaRollupAddress = await config.getLineaRollupContract().getAddress();
|
||||
const l1SecurityCouncilAddress = await l1AccountManager.whaleAccount(3).getAddress();
|
||||
|
||||
const lineaRollupV6 = LineaRollupV6__factory.connect(lineaRollupAddress, config.getL1Provider());
|
||||
|
||||
for (const role of LINEA_ROLLUP_V6_ROLES) {
|
||||
const hasRole = await lineaRollupV6.hasRole(role, l1SecurityCouncilAddress);
|
||||
expect(hasRole).toBeTruthy();
|
||||
}
|
||||
|
||||
const [pauseTypeRoleSetEvents, unPauseTypeRoleSetEvents] = await Promise.all([
|
||||
getEvents(lineaRollupV6, lineaRollupV6.filters.PauseTypeRoleSet()),
|
||||
getEvents(lineaRollupV6, lineaRollupV6.filters.UnPauseTypeRoleSet()),
|
||||
]);
|
||||
|
||||
expect(pauseTypeRoleSetEvents.length).toEqual(LINEA_ROLLUP_PAUSE_TYPES_ROLES.length);
|
||||
expect(unPauseTypeRoleSetEvents.length).toEqual(LINEA_ROLLUP_UNPAUSE_TYPES_ROLES.length);
|
||||
});
|
||||
|
||||
it("Check L1 data submission and finalization", async () => {
|
||||
const lineaRollupAddress = await config.getLineaRollupContract().getAddress();
|
||||
const lineaRollupV6 = LineaRollupV6__factory.connect(lineaRollupAddress, config.getL1Provider());
|
||||
|
||||
const currentL2BlockNumber = await lineaRollupV6.currentL2BlockNumber();
|
||||
|
||||
console.log("Waiting for DataSubmittedV3 used to finalize with proof...");
|
||||
await waitForEvents(lineaRollupV6, lineaRollupV6.filters.DataSubmittedV3(), 1_000);
|
||||
|
||||
console.log("Waiting for the first DataFinalizedV3 event with proof...");
|
||||
const [dataFinalizedEvent] = await waitForEvents(
|
||||
lineaRollupV6,
|
||||
lineaRollupV6.filters.DataFinalizedV3(currentL2BlockNumber + 1n),
|
||||
1_000,
|
||||
);
|
||||
|
||||
const [lastBlockFinalized, newStateRootHash] = await Promise.all([
|
||||
lineaRollupV6.currentL2BlockNumber(),
|
||||
lineaRollupV6.stateRootHashes(dataFinalizedEvent.args.endBlockNumber),
|
||||
]);
|
||||
|
||||
expect(lastBlockFinalized).toBeGreaterThanOrEqual(dataFinalizedEvent.args.endBlockNumber);
|
||||
expect(newStateRootHash).toEqual(dataFinalizedEvent.args.finalStateRootHash);
|
||||
|
||||
console.log("Finalization with proof done.");
|
||||
}, 150_000);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user