Skip to content

Commit

Permalink
small e2e CI tweaks (#33)
Browse files Browse the repository at this point in the history
improve e2e test with dedicated liveness account

Signed-off-by: Pedro Novais <1478752+jpnovais@users.noreply.github.com>
  • Loading branch information
jpnovais authored Oct 1, 2024
1 parent 405d683 commit 41cec7c
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 76 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/reuse-run-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ jobs:
docker container ls -a
- name: Run e2e tests
id: run_e2e_tests
timeout-minutes: 25
run: |
pnpm run -F e2e test:e2e:local
- name: Show e2e tests result
Expand All @@ -157,9 +158,9 @@ jobs:
run: |
mkdir -p docker_logs
docker ps -a >> docker_logs/docker_ps.txt
docker logs coordinator --since 1h &>> docker_logs/coordinator.txt
docker logs prover --since 1h &>> docker_logs/prover.txt
docker logs prover-v3 --since 1h &>> docker_logs/prover-v3.txt;
docker logs coordinator --since 1h &>> docker_logs/coordinator.txt
docker logs shomei --since 1h &>> docker_logs/shomei.txt
docker logs zkbesu-shomei --since 1h &>> docker_logs/zkbesu-shomei.txt
docker logs shomei-frontend --since 1h &>> docker_logs/shomei-frontend.txt
Expand Down
4 changes: 2 additions & 2 deletions config/coordinator/coordinator-docker.config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public-key="4a788ad6fa008beed58de6418369717d7492f37d173d70e2c26d9737e2c6eeae9294

[message-anchoring-service]
disabled=false
polling-interval="PT10S"
polling-interval="PT1S"
max-messages-to-anchor=100

[l2-network-gas-pricing]
Expand Down Expand Up @@ -249,7 +249,7 @@ disabled=false
[l1-dynamic-gas-price-cap-service.gas-price-cap-calculation]
adjustment-constant=25
blob-adjustment-constant=25
finalization-target-max-delay="PT2M"
finalization-target-max-delay="PT30S"
gas-fee-percentile-window="PT1M"
gas-fee-percentile-window-leeway="PT10S"
gas-fee-percentile=10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ class CoordinatorConfigTest {
)

private val messageAnchoringServiceConfig = MessageAnchoringServiceConfig(
pollingInterval = Duration.parse("PT10S"),
pollingInterval = Duration.parse("PT1S"),
maxMessagesToAnchor = 100U
)

Expand Down Expand Up @@ -470,7 +470,7 @@ class CoordinatorConfigTest {
gasPriceCapCalculation = L1DynamicGasPriceCapServiceConfig.GasPriceCapCalculation(
adjustmentConstant = 25U,
blobAdjustmentConstant = 25U,
finalizationTargetMaxDelay = Duration.parse("PT2M"),
finalizationTargetMaxDelay = Duration.parse("PT30S"),
gasFeePercentileWindow = Duration.parse("PT1M"),
gasFeePercentileWindowLeeway = Duration.parse("PT10S"),
gasFeePercentile = 10.0,
Expand Down
2 changes: 1 addition & 1 deletion docker/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ services:
coordinator:
hostname: coordinator
container_name: coordinator
image: consensys/linea-coordinator:${COORDINATOR_TAG:-8a5690e}
image: consensys/linea-coordinator:${COORDINATOR_TAG:-2ee4363}
platform: linux/amd64
profiles: [ "l2", "debug" ]
depends_on:
Expand Down
1 change: 1 addition & 0 deletions e2e/env-setup/custom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ declare global {
var LINEA_ROLLUP_CONTRACT_ADDRESS: string;
var L1_ACCOUNT_0_PRIVATE_KEY: string;
var L2_ACCOUNT_0_PRIVATE_KEY: string;
var L2_ACCOUNT_1_PRIVATE_KEY: string;
var L1_DEPLOYER_ACCOUNT_PRIVATE_KEY: string;
var L2_DEPLOYER_ACCOUNT_PRIVATE_KEY: string;
var TRANSACTION_CALLDATA_LIMIT: number;
Expand Down
2 changes: 2 additions & 0 deletions e2e/env-setup/setup-local-deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import {
L2_ACCOUNT_0,
L2_ACCOUNT_0_PRIVATE_KEY,
L2_ACCOUNT_1_PRIVATE_KEY,
L1_DEPLOYER_ACCOUNT_PRIVATE_KEY,
L2_DEPLOYER_ACCOUNT_PRIVATE_KEY,
INITIAL_WITHDRAW_LIMIT,
Expand Down Expand Up @@ -70,6 +71,7 @@ beforeAll(async () => {
global.lineaRollup = lineaRollup;
global.useLocalSetup = true;
global.L2_ACCOUNT_0_PRIVATE_KEY = L2_ACCOUNT_0_PRIVATE_KEY;
global.L2_ACCOUNT_1_PRIVATE_KEY = L2_ACCOUNT_1_PRIVATE_KEY;
global.L1_DEPLOYER_ACCOUNT_PRIVATE_KEY = L1_DEPLOYER_ACCOUNT_PRIVATE_KEY;
global.L2_DEPLOYER_ACCOUNT_PRIVATE_KEY = L2_DEPLOYER_ACCOUNT_PRIVATE_KEY;
global.TRANSACTION_CALLDATA_LIMIT = TRANSACTION_CALLDATA_LIMIT;
Expand Down
2 changes: 2 additions & 0 deletions e2e/env-setup/setup-local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
MESSAGE_SERVICE_ADDRESS,
L1_ACCOUNT_0_PRIVATE_KEY,
L2_ACCOUNT_0_PRIVATE_KEY,
L2_ACCOUNT_1_PRIVATE_KEY,
TRANSACTION_CALLDATA_LIMIT,
OPERATOR_0_PRIVATE_KEY,
SHOMEI_ENDPOINT,
Expand Down Expand Up @@ -77,6 +78,7 @@ beforeAll(async () => {
global.chainId = CHAIN_ID;
global.L1_ACCOUNT_0_PRIVATE_KEY = L1_ACCOUNT_0_PRIVATE_KEY;
global.L2_ACCOUNT_0_PRIVATE_KEY = L2_ACCOUNT_0_PRIVATE_KEY;
global.L2_ACCOUNT_1_PRIVATE_KEY = L2_ACCOUNT_1_PRIVATE_KEY;
global.L1_DEPLOYER_ACCOUNT_PRIVATE_KEY = L1_DEPLOYER_ACCOUNT_PRIVATE_KEY;
global.L2_DEPLOYER_ACCOUNT_PRIVATE_KEY = L2_DEPLOYER_ACCOUNT_PRIVATE_KEY;
global.TRANSACTION_CALLDATA_LIMIT = TRANSACTION_CALLDATA_LIMIT;
Expand Down
46 changes: 14 additions & 32 deletions e2e/src/messaging.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { Wallet, ethers } from "ethers";
import { beforeAll, describe, expect, it } from "@jest/globals";
import { encodeFunctionCall, sendXTransactions, waitForEvents } from "./utils/utils";
import {
encodeFunctionCall,
sendTransactionsToGenerateTrafficWithInterval,
waitForEvents
} from "./utils/utils";
import { getAndIncreaseFeeData } from "./utils/helpers";
import { MESSAGE_SENT_EVENT_SIGNATURE } from "./utils/constants";

const messagingTestSuite = (title: string) => {
describe(title, () => {
let l1Account: Wallet;
let l2Account0: Wallet;
let l2AccountForLiveness: Wallet;

beforeAll(() => {
l1Account = new Wallet(L1_ACCOUNT_0_PRIVATE_KEY, l1Provider);
l2Account0 = new Wallet(L2_ACCOUNT_0_PRIVATE_KEY, l2Provider);
l2AccountForLiveness = new Wallet(L2_ACCOUNT_1_PRIVATE_KEY, l2Provider);
});

describe("Message Service L1 -> L2", () => {
Expand Down Expand Up @@ -46,33 +52,19 @@ const messagingTestSuite = (title: string) => {

const receipt = await tx.wait();

console.log("Moving the L2 chain forward to trigger anchoring...");
const intervalId = await sendTransactionsToGenerateTrafficWithInterval(l2AccountForLiveness);

const [messageSentEvent] = receipt.logs.filter((log) => log.topics[0] === MESSAGE_SENT_EVENT_SIGNATURE);
const messageHash = messageSentEvent.topics[3];

console.log(`L1 message sent: messageHash=${messageHash} transaction=${JSON.stringify(tx)}`);

//Extra transactions to trigger anchoring
console.log("Moving the L2 chain forward to trigger anchoring...");

const [maxPriorityFeePerGas2, maxFeePerGas2] = getAndIncreaseFeeData(await l2Provider.getFeeData());
await sendXTransactions(
l2Account0,
{
to: "0x8D97689C9818892B700e27F316cc3E41e17fBeb9",
value: ethers.utils.parseEther("0.0001"),
maxPriorityFeePerGas: maxPriorityFeePerGas2,
maxFeePerGas: maxFeePerGas2,
},
5,
);

console.log("Waiting for MessageClaimed event on L2.");
const [messageClaimedEvent] = await waitForEvents(
l2MessageService,
l2MessageService.filters.MessageClaimed(messageHash),
1_000,
);

clearInterval(intervalId);
console.log(`Message claimed on L2: ${JSON.stringify(messageClaimedEvent)}`);
expect(messageClaimedEvent).toBeDefined();
},
Expand Down Expand Up @@ -116,24 +108,14 @@ const messagingTestSuite = (title: string) => {
console.log(`L2 message sent: messageHash=${messageHash} transaction=${JSON.stringify(tx)}`);

console.log("Moving the L2 chain forward to trigger conflation...");
const [maxPriorityFeePerGas2, maxFeePerGas2] = getAndIncreaseFeeData(await l2Provider.getFeeData());
await sendXTransactions(
l2Account0,
{
to: "0x8D97689C9818892B700e27F316cc3E41e17fBeb9",
value: ethers.utils.parseEther("0.0001"),
maxPriorityFeePerGas: maxPriorityFeePerGas2,
maxFeePerGas: maxFeePerGas2,
},
10,
);
const intervalId = await sendTransactionsToGenerateTrafficWithInterval(l2AccountForLiveness);

console.log("Waiting for MessageClaimed event on L1.");
const [messageClaimedEvent] = await waitForEvents(
lineaRollup,
lineaRollup.filters.MessageClaimed(messageHash),
1_000,
lineaRollup.filters.MessageClaimed(messageHash)
);
clearInterval(intervalId);

console.log(`Message claimed on L1: ${JSON.stringify(messageClaimedEvent)}`);
expect(messageClaimedEvent).toBeDefined();
Expand Down
63 changes: 28 additions & 35 deletions e2e/src/restart.spec.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,47 @@
import { describe, expect, it } from "@jest/globals";
import {describe, expect, it} from "@jest/globals";
import {
getEvents,
execDockerCommand,
sendXTransactions,
waitForEvents,
getMessageSentEventFromLogs,
sendMessage,
sendTransactionsToGenerateTrafficWithInterval,
} from "./utils/utils";
import { getAndIncreaseFeeData } from "./utils/helpers";
import { Wallet, ethers } from "ethers";
// import { MessageEvent } from "./utils/types";
import {getAndIncreaseFeeData} from "./utils/helpers";
import {Wallet, ethers} from "ethers";

const coordinatorRestartTestSuite = (title: string) => {
describe(title, () => {
it("When the coordinator restarts it should resume blob submission and finalization", async () => {
const l2Account0 = new Wallet(L2_ACCOUNT_0_PRIVATE_KEY, l2Provider);
const l2AccountForLiveness = new Wallet(L2_ACCOUNT_1_PRIVATE_KEY, l2Provider);

console.log("Moving the L2 chain forward to trigger conflation...");
const intervalId = await sendTransactionsToGenerateTrafficWithInterval(l2AccountForLiveness);

// await for a finalization to happen on L1
await Promise.all([
waitForEvents(lineaRollup, lineaRollup.filters.DataSubmittedV2(), 0, "latest"),
waitForEvents(lineaRollup, lineaRollup.filters.DataFinalized(), 0, "latest"),
]);

await execDockerCommand("stop", "coordinator");

const currentBlockNumberBeforeRestart = await l1Provider.getBlockNumber();

const [dataSubmittedEventsBeforeRestart, dataFinalizedEventsBeforeRestart] = await Promise.all([
getEvents(lineaRollup, lineaRollup.filters.DataSubmittedV2(), 0, currentBlockNumberBeforeRestart),
getEvents(lineaRollup, lineaRollup.filters.DataFinalized(), 0, currentBlockNumberBeforeRestart),
]);

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.toNumber()).toBeGreaterThan(0)
expect(lastDataFinalizedEventsBeforeRestart.args.lastBlockFinalized.toNumber()).toBeGreaterThan(0)

await execDockerCommand("start", "coordinator");

const currentBlockNumberAfterRestart = await l1Provider.getBlockNumber();

console.log("Moving the L2 chain forward to trigger conflation...");
const [maxPriorityFeePerGas, maxFeePerGas] = getAndIncreaseFeeData(await l2Provider.getFeeData());
await sendXTransactions(
l2Account0,
{
to: "0x8D97689C9818892B700e27F316cc3E41e17fBeb9",
value: ethers.utils.parseEther("0.0001"),
maxPriorityFeePerGas,
maxFeePerGas,
},
20,
);

console.log("Waiting for DataSubmittedV2 event after coordinator restart...");
const [dataSubmittedV2EventAfterRestart] = await waitForEvents(
lineaRollup,
Expand All @@ -68,14 +65,16 @@ const coordinatorRestartTestSuite = (title: string) => {
},
);
console.log(`New DataFinalized event found: event=${JSON.stringify(dataFinalizedEventAfterRestart)}`);
clearInterval(intervalId)

expect(dataFinalizedEventAfterRestart.args.lastBlockFinalized.toNumber()).toBeGreaterThan(
lastDataFinalizedEventsBeforeRestart.args.lastBlockFinalized.toNumber(),
);
}, 300_000);

it("When the coordinator restarts it should resume anchoring", async () => {
const l1MessageSender = new Wallet(L1_ACCOUNT_0_PRIVATE_KEY, l1Provider);
const l2MessageSender = new Wallet(L2_ACCOUNT_0_PRIVATE_KEY, l2Provider);
const l2AccountForLiveness = new Wallet(L2_ACCOUNT_1_PRIVATE_KEY, l2Provider);

// Send Messages L1 -> L2
const messageFee = ethers.utils.parseEther("0.0001");
Expand Down Expand Up @@ -112,7 +111,7 @@ const coordinatorRestartTestSuite = (title: string) => {
// Wait for L2 Anchoring
const lastNewL1MessageNumber = l1Messages.slice(-1)[0].messageNumber;

console.log("Waiting for the anchoring using rolling hash...");
console.log(`Waiting L1->L2 anchoring messageNumber=${lastNewL1MessageNumber}`);
await waitForEvents(l2MessageService, l2MessageService.filters.RollingHashUpdated(lastNewL1MessageNumber), 1_000);

// Restart Coordinator
Expand Down Expand Up @@ -144,22 +143,14 @@ const coordinatorRestartTestSuite = (title: string) => {

console.log("Moving the L2 chain forward to trigger anchoring...");
// Using 5 messages to give the coordinator time to restart
const [maxPriorityFeePerGas, maxFeePerGas] = getAndIncreaseFeeData(await l2Provider.getFeeData());
await sendXTransactions(
l2MessageSender,
{
to: "0x8D97689C9818892B700e27F316cc3E41e17fBeb9",
value: ethers.utils.parseEther("0.0001"),
maxPriorityFeePerGas,
maxFeePerGas,
},
5,
);
const intervalId = await sendTransactionsToGenerateTrafficWithInterval(l2AccountForLiveness);

// Wait for messages to be anchored on L2
const lastNewL1MessageNumberAfterRestart = l1MessagesAfterRestart.slice(-1)[0].messageNumber;

console.log("Waiting for the anchoring using rolling hash after coordinator restart...");
console.log(
`Waiting L1->L2 anchoring after coordinator restart messageNumber=${lastNewL1MessageNumberAfterRestart}`
);
const [rollingHashUpdatedEventAfterRestart] = await waitForEvents(
l2MessageService,
l2MessageService.filters.RollingHashUpdated(lastNewL1MessageNumberAfterRestart),
Expand All @@ -171,6 +162,8 @@ const coordinatorRestartTestSuite = (title: string) => {
l2MessageService.lastAnchoredL1MessageNumber(),
]);

clearInterval(intervalId)

expect(lastNewMessageRollingHashAfterRestart).toEqual(rollingHashUpdatedEventAfterRestart.args.rollingHash);
expect(lastAnchoredL1MessageNumberAfterRestart).toEqual(lastNewL1MessageNumberAfterRestart);
}, 300_000);
Expand Down
3 changes: 2 additions & 1 deletion e2e/src/utils/constants.local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const L1_ACCOUNT_0_PRIVATE_KEY = "0x47e179ec197488593b187f80a00eb0da91f1b
export const L2_ACCOUNT_0 = "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73";
// WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE
export const L2_ACCOUNT_0_PRIVATE_KEY = "0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63";
export const L2_ACCOUNT_1_PRIVATE_KEY = "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3";

export const OPERATOR_0 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8";
// WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE
Expand Down Expand Up @@ -56,4 +57,4 @@ export const SHOMEI_ENDPOINT = new URL("http://localhost:8998");
export const SHOMEI_FRONTEND_ENDPOINT = new URL("http://localhost:8889");
export const SEQUENCER_ENDPOINT = new URL("http://localhost:8545")

export const CONTRACT_GAS_OPTIMIZATION_SWITCH_BLOCK = 12;
export const CONTRACT_GAS_OPTIMIZATION_SWITCH_BLOCK = 12;
22 changes: 20 additions & 2 deletions e2e/src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BlockTag } from "@ethersproject/providers";
import * as fs from "fs";
import assert from "assert";
import { Contract, ContractReceipt, PayableOverrides, Wallet, ethers } from "ethers";
import {Contract, ContractReceipt, PayableOverrides, Wallet, ethers} from "ethers";
import path from "path";
import { exec } from "child_process";
import { L2MessageService, LineaRollup } from "../typechain";
Expand Down Expand Up @@ -92,7 +92,7 @@ export async function getEvents<TContract extends LineaRollup | L2MessageService
export async function waitForEvents<TContract extends LineaRollup | L2MessageService, TEvent extends TypedEvent>(
contract: TContract,
eventFilter: TypedEventFilter<TEvent>,
pollingInterval: number,
pollingInterval: number = 500,
fromBlock?: BlockTag,
toBlock?: BlockTag,
criteria?: (events: TEvent[]) => Promise<TEvent[]>,
Expand Down Expand Up @@ -170,6 +170,24 @@ export async function sendXTransactions(
}
}

export async function sendTransactionsToGenerateTrafficWithInterval(
signer: Wallet,
pollingInterval: number = 1000,
) {
const [maxPriorityFeePerGas, maxFeePerGas] = getAndIncreaseFeeData(await signer.provider.getFeeData());
const transactionRequest = {
to: signer.address,
value: ethers.utils.parseEther("0.000001"),
maxPriorityFeePerGas: maxPriorityFeePerGas,
maxFeePerGas: maxFeePerGas,
}

return setInterval(async function () {
const tx = await signer.sendTransaction(transactionRequest);
await tx.wait();
}, pollingInterval);
}

export function getMessageSentEventFromLogs<T extends Contract>(
contract: T,
receipts: ContractReceipt[],
Expand Down

0 comments on commit 41cec7c

Please sign in to comment.