From f9c49099c558d130cb3e2dd573e15b97c54487fe Mon Sep 17 00:00:00 2001 From: Victorien Gauch <85494462+VGau@users.noreply.github.com> Date: Mon, 6 Jan 2025 10:50:44 +0100 Subject: [PATCH] Feat: add winston logger in e2e tests (#489) * feat: add winston logger in e2e tests * fix: rename appendTestName function to prefixWithTestName * fix: change some log level --- e2e/jest.config.ts | 1 + e2e/jest.testnet.config.ts | 5 +- e2e/package.json | 3 +- e2e/src/bridge-tokens.spec.ts | 40 +++---- e2e/src/common/deployments.ts | 4 +- e2e/src/common/utils.ts | 13 +- e2e/src/config/global.d.ts | 10 ++ e2e/src/config/jest/global-setup.ts | 17 ++- e2e/src/config/jest/setup.ts | 3 + e2e/src/config/logger/base-logger.ts | 17 +++ e2e/src/config/logger/index.ts | 1 + e2e/src/config/logger/logger.ts | 62 ++++++++++ .../tests-config/accounts/account-manager.ts | 19 +-- e2e/src/gas-limit.spec.ts | 8 +- e2e/src/l2.spec.ts | 2 +- e2e/src/messaging.spec.ts | 83 +++++++------ e2e/src/restart.spec.ts | 31 ++--- e2e/src/submission-finalization.spec.ts | 22 ++-- e2e/src/transaction-exclusion.spec.ts | 6 +- e2e/tsconfig.json | 1 + pnpm-lock.yaml | 112 ++++++------------ 21 files changed, 267 insertions(+), 193 deletions(-) create mode 100644 e2e/src/config/global.d.ts create mode 100644 e2e/src/config/jest/setup.ts create mode 100644 e2e/src/config/logger/base-logger.ts create mode 100644 e2e/src/config/logger/index.ts create mode 100644 e2e/src/config/logger/logger.ts diff --git a/e2e/jest.config.ts b/e2e/jest.config.ts index a70a68e5..1ee0d495 100644 --- a/e2e/jest.config.ts +++ b/e2e/jest.config.ts @@ -8,6 +8,7 @@ const config: Config = { verbose: true, globalSetup: "./config/jest/global-setup.ts", globalTeardown: "./config/jest/global-teardown.ts", + setupFilesAfterEnv: ["./config/jest/setup.ts"], testTimeout: 3 * 60 * 1000, maxConcurrency: 7, maxWorkers: "75%", diff --git a/e2e/jest.testnet.config.ts b/e2e/jest.testnet.config.ts index 33efc4af..fd88c6e1 100644 --- a/e2e/jest.testnet.config.ts +++ b/e2e/jest.testnet.config.ts @@ -6,8 +6,11 @@ const config: Config = { rootDir: "src", testRegex: ".spec.ts$", verbose: true, - maxWorkers: "50%", + setupFilesAfterEnv: ["./config/jest/setup.ts"], testTimeout: 3 * 60 * 1000, + maxConcurrency: 7, + maxWorkers: "75%", + workerThreads: true, }; export default config; diff --git a/e2e/package.json b/e2e/package.json index 14249d1d..cdb04783 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -28,6 +28,7 @@ "ethers": "6.13.3", "jest": "29.7.0", "ts-jest": "29.2.5", - "typechain": "8.3.2" + "typechain": "8.3.2", + "winston": "3.17.0" } } diff --git a/e2e/src/bridge-tokens.spec.ts b/e2e/src/bridge-tokens.spec.ts index 8b00894b..40071da4 100644 --- a/e2e/src/bridge-tokens.spec.ts +++ b/e2e/src/bridge-tokens.spec.ts @@ -24,12 +24,12 @@ describe("Bridge ERC20 Tokens L1 -> L2 and L2 -> L1", () => { const l1Token = config.getL1TokenContract(); const l1Provider = config.getL1Provider(); - console.log("Minting ERC20 tokens to L1 Account"); + logger.debug("Minting ERC20 tokens to L1 Account"); let { maxPriorityFeePerGas: l1MaxPriorityFeePerGas, maxFeePerGas: l1MaxFeePerGas } = await l1Provider.getFeeData(); let nonce = await l1Provider.getTransactionCount(l1Account.address, "pending"); - console.log("Minting and approving tokens to L1 TokenBridge"); + logger.debug("Minting and approving tokens to L1 TokenBridge"); await Promise.all([ ( @@ -52,9 +52,9 @@ describe("Bridge ERC20 Tokens L1 -> L2 and L2 -> L1", () => { const l1TokenAddress = await l1Token.getAddress(); const allowanceL1Account = await l1Token.allowance(l1Account.address, l1TokenBridgeAddress); - console.log("Current allowance of L1 account to L1 TokenBridge is :", allowanceL1Account.toString()); + logger.info(`Current allowance of L1 account to L1 TokenBridge is ${allowanceL1Account.toString()}`); - console.log("Calling the bridgeToken function on the L1 TokenBridge contract"); + logger.debug("Calling the bridgeToken function on the L1 TokenBridge contract"); ({ maxPriorityFeePerGas: l1MaxPriorityFeePerGas, maxFeePerGas: l1MaxFeePerGas } = await l1Provider.getFeeData()); nonce = await l1Provider.getTransactionCount(l1Account.address, "pending"); @@ -79,18 +79,18 @@ describe("Bridge ERC20 Tokens L1 -> L2 and L2 -> L1", () => { ); const l1TokenBalance = await l1Token.balanceOf(l1Account.address); - console.log("Token balance of L1 account :", l1TokenBalance.toString()); + logger.info(`Token balance of L1 account is ${l1TokenBalance.toString()}`); expect(l1TokenBalance).toEqual(0n); - console.log("Waiting for MessageSent event on L1."); + logger.info("Waiting for MessageSent event on L1."); const messageNumber = messageSentEvent[messageSentEventMessageNumberIndex]; const messageHash = messageSentEvent[messageSentEventMessageHashIndex]; - console.log(`Message sent on L1 : messageHash=${messageHash}`); + logger.info(`Message sent on L1. messageHash=${messageHash}`); - console.log("Waiting for anchoring..."); + logger.info("Waiting for anchoring..."); const [rollingHashUpdatedEvent] = await waitForEvents( l2MessageService, @@ -106,9 +106,9 @@ describe("Bridge ERC20 Tokens L1 -> L2 and L2 -> L1", () => { expect(anchoredStatus).toBeGreaterThan(0); - console.log(`Message anchored : ${JSON.stringify(rollingHashUpdatedEvent)}`); + logger.info(`Message anchored. event=${JSON.stringify(rollingHashUpdatedEvent)}`); - console.log("Waiting for MessageClaimed event on L2..."); + logger.info("Waiting for MessageClaimed event on L2..."); const [claimedEvent] = await waitForEvents(l2MessageService, l2MessageService.filters.MessageClaimed(messageHash)); expect(claimedEvent).not.toBeNull(); @@ -116,14 +116,14 @@ describe("Bridge ERC20 Tokens L1 -> L2 and L2 -> L1", () => { const [newTokenDeployed] = await waitForEvents(l2TokenBridge, l2TokenBridge.filters.NewTokenDeployed()); expect(newTokenDeployed).not.toBeNull(); - console.log(`Message claimed on L2 : ${JSON.stringify(claimedEvent)}.`); + logger.info(`Message claimed on L2. event=${JSON.stringify(claimedEvent)}.`); const l2Token = config.getL2BridgedTokenContract(newTokenDeployed.args.bridgedToken); - console.log("Verify the token balance on L2"); + logger.info("Verify the token balance on L2"); const l2TokenBalance = await l2Token.balanceOf(l2Account.address); - console.log("Token balance of L2 account :", l2TokenBalance.toString()); + logger.info(`Token balance of L2 account is ${l2TokenBalance.toString()}`); expect(l2TokenBalance).toEqual(bridgeAmount); }); @@ -163,10 +163,10 @@ describe("Bridge ERC20 Tokens L1 -> L2 and L2 -> L1", () => { ]); const allowanceL2Account = await l2Token.allowance(l2Account.address, l2TokenBridge.getAddress()); - console.log("Current allowance of L2 account to L2 TokenBridge is :", allowanceL2Account.toString()); - console.log("Current balance of L2 account is :", await l2Token.balanceOf(l2Account)); + logger.info(`Current allowance of L2 account to L2 TokenBridge is ${allowanceL2Account.toString()}`); + logger.info(`Current balance of L2 account is ${await l2Token.balanceOf(l2Account)}`); - console.log("Calling the bridgeToken function on the L2 TokenBridge contract"); + logger.debug("Calling the bridgeToken function on the L2 TokenBridge contract"); nonce = await l2Provider.getTransactionCount(l2Account.address, "pending"); @@ -189,22 +189,22 @@ describe("Bridge ERC20 Tokens L1 -> L2 and L2 -> L1", () => { ); const messageHash = messageSentEvent[messageSentEventMessageHashIndex]; - console.log("Waiting for L1 MessageClaimed event."); + logger.info("Waiting for L1 MessageClaimed event."); const [claimedEvent] = await waitForEvents(lineaRollup, lineaRollup.filters.MessageClaimed(messageHash)); expect(claimedEvent).not.toBeNull(); - console.log(`Message claimed on L1 : ${JSON.stringify(claimedEvent)}`); + logger.info(`Message claimed on L1. event=${JSON.stringify(claimedEvent)}`); const [newTokenDeployed] = await waitForEvents(l1TokenBridge, l1TokenBridge.filters.NewTokenDeployed()); expect(newTokenDeployed).not.toBeNull(); const l1BridgedToken = config.getL1BridgedTokenContract(newTokenDeployed.args.bridgedToken); - console.log("Verify the token balance on L1"); + logger.info("Verify the token balance on L1"); const l1BridgedTokenBalance = await l1BridgedToken.balanceOf(l1Account.address); - console.log("Token balance of L1 account :", l1BridgedTokenBalance.toString()); + logger.info(`Token balance of L1 account is ${l1BridgedTokenBalance.toString()}`); expect(l1BridgedTokenBalance).toEqual(bridgeAmount); }); diff --git a/e2e/src/common/deployments.ts b/e2e/src/common/deployments.ts index 24870f3c..dbde7903 100644 --- a/e2e/src/common/deployments.ts +++ b/e2e/src/common/deployments.ts @@ -56,7 +56,7 @@ export async function deployUpgradableContractWithProxyAdmin( export async function execDockerCommand(command: string, containerName: string): Promise { const dockerCommand = `docker ${command} ${containerName}`; - console.log(`Executing: ${dockerCommand}...`); + logger.info(`Executing ${dockerCommand}...`); return new Promise((resolve, reject) => { exec(dockerCommand, (error, stdout, stderr) => { if (error) { - console.error(`Error executing (${dockerCommand}): ${stderr}`); + logger.error(`Error executing (${dockerCommand}). error=${stderr}`); reject(error); } - console.log(`Execution success (${dockerCommand}): ${stdout}`); + logger.info(`Execution success (${dockerCommand}). output=${stdout}`); resolve(stdout); }); }); diff --git a/e2e/src/config/global.d.ts b/e2e/src/config/global.d.ts new file mode 100644 index 00000000..dd0b3bd5 --- /dev/null +++ b/e2e/src/config/global.d.ts @@ -0,0 +1,10 @@ +/* eslint-disable no-var */ + +import { Logger } from "winston"; + +declare global { + var stopL2TrafficGeneration: () => void; + var logger: Logger; +} + +export {}; diff --git a/e2e/src/config/jest/global-setup.ts b/e2e/src/config/jest/global-setup.ts index 1a7d693b..8fe32c97 100644 --- a/e2e/src/config/jest/global-setup.ts +++ b/e2e/src/config/jest/global-setup.ts @@ -5,21 +5,20 @@ import { deployContract } from "../../common/deployments"; import { DummyContract__factory, TestContract__factory, OpcodeTestContract__factory } from "../../typechain"; import { etherToWei, sendTransactionsToGenerateTrafficWithInterval } from "../../common/utils"; import { EMPTY_CONTRACT_CODE } from "../../common/constants"; +import { createTestLogger } from "../logger"; -declare global { - var stopL2TrafficGeneration: () => void; -} +const logger = createTestLogger(); export default async (): Promise => { 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"); + logger.info("Configuring once-off prerequisite contracts"); await configureOnceOffPrerequisities(); } - console.log("Generating L2 traffic..."); + logger.info("Generating L2 traffic..."); const pollingAccount = await config.getL2AccountManager().generateAccount(etherToWei("200")); const stopPolling = await sendTransactionsToGenerateTrafficWithInterval(pollingAccount, 2_000); @@ -71,8 +70,8 @@ async function configureOnceOffPrerequisities() { ).wait(), ]); - 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(`L2 OpcodeTest contract deployed at address: ${await opcodeTestContract.getAddress()}`); + logger.info(`L1 Dummy contract deployed. address=${await dummyContract.getAddress()}`); + logger.info(`L2 Dummy contract deployed. address=${await l2DummyContract.getAddress()}`); + logger.info(`L2 Test contract deployed. address=${await l2TestContract.getAddress()}`); + logger.info(`L2 OpcodeTest contract deployed. address=${await opcodeTestContract.getAddress()}`); } diff --git a/e2e/src/config/jest/setup.ts b/e2e/src/config/jest/setup.ts new file mode 100644 index 00000000..9e15b56f --- /dev/null +++ b/e2e/src/config/jest/setup.ts @@ -0,0 +1,3 @@ +import { createTestLogger } from "../logger"; + +global.logger = createTestLogger(); diff --git a/e2e/src/config/logger/base-logger.ts b/e2e/src/config/logger/base-logger.ts new file mode 100644 index 00000000..8cd81330 --- /dev/null +++ b/e2e/src/config/logger/base-logger.ts @@ -0,0 +1,17 @@ +import { createLogger, format, transports, Logger } from "winston"; + +const { splat, combine, colorize, timestamp, printf } = format; + +export const baseLogger: Logger = createLogger({ + level: process.env.LOG_LEVEL || "info", + format: combine( + timestamp(), + colorize({ level: true }), + splat(), + printf(({ level, message, timestamp, testName }) => { + const testContext = testName ? ` test=${testName}` : ""; + return `timestamp=${timestamp} level=${level}${testContext} | message=${message}`; + }), + ), + transports: [new transports.Console()], +}); diff --git a/e2e/src/config/logger/index.ts b/e2e/src/config/logger/index.ts new file mode 100644 index 00000000..b191813f --- /dev/null +++ b/e2e/src/config/logger/index.ts @@ -0,0 +1 @@ +export { createTestLogger } from "./logger"; diff --git a/e2e/src/config/logger/logger.ts b/e2e/src/config/logger/logger.ts new file mode 100644 index 00000000..180efc89 --- /dev/null +++ b/e2e/src/config/logger/logger.ts @@ -0,0 +1,62 @@ +import { Logger, LeveledLogMethod } from "winston"; +import { baseLogger } from "./base-logger"; + +type LogLevel = "error" | "warn" | "info" | "verbose" | "debug" | "silly"; + +function getActiveTestName(): string | undefined { + if (typeof expect !== "function" || typeof expect.getState !== "function") { + return undefined; + } + + const { currentTestName, currentConcurrentTestName } = expect.getState() || {}; + + if (!currentConcurrentTestName) { + return currentTestName; + } + + return currentConcurrentTestName(); +} + +function prefixWithTestName(level: LogLevel, args: unknown[]): Logger { + const testName = getActiveTestName(); + + if (!testName) { + return baseLogger[level as keyof Logger](...args); + } + + const [firstArg] = args; + + if (typeof firstArg === "string") { + return baseLogger[level](firstArg, { testName }); + } + + if (firstArg && typeof firstArg === "object" && !Array.isArray(firstArg)) { + return baseLogger[level]({ testName, ...firstArg }); + } + + return baseLogger[level as keyof Logger](...args); +} + +export function createTestLogger(): Logger { + return { + ...baseLogger, + error(...args: Parameters) { + return prefixWithTestName("error", args); + }, + warn(...args: Parameters) { + return prefixWithTestName("warn", args); + }, + info(...args: Parameters) { + return prefixWithTestName("info", args); + }, + verbose(...args: Parameters) { + return prefixWithTestName("verbose", args); + }, + debug(...args: Parameters) { + return prefixWithTestName("debug", args); + }, + silly(...args: Parameters) { + return prefixWithTestName("silly", args); + }, + } as Logger; +} diff --git a/e2e/src/config/tests-config/accounts/account-manager.ts b/e2e/src/config/tests-config/accounts/account-manager.ts index f0f4c3cf..ab4f5992 100644 --- a/e2e/src/config/tests-config/accounts/account-manager.ts +++ b/e2e/src/config/tests-config/accounts/account-manager.ts @@ -1,7 +1,9 @@ import { ethers, NonceManager, Provider, TransactionResponse, Wallet } from "ethers"; import { Mutex } from "async-mutex"; +import type { Logger } from "winston"; import Account from "./account"; import { etherToWei } from "../../../common/utils"; +import { createTestLogger } from "../../../config/logger"; interface IAccountManager { whaleAccount(accIndex?: number): NonceManager; @@ -29,6 +31,7 @@ abstract class AccountManager implements IAccountManager { protected provider: Provider; protected accountWallets: NonceManager[]; private whaleAccountMutex: Mutex; + private logger: Logger; constructor(provider: Provider, whaleAccounts: Account[], chainId: number) { this.provider = provider; @@ -38,6 +41,8 @@ abstract class AccountManager implements IAccountManager { (account) => new NonceManager(getWallet(this.provider, account.privateKey)), ); this.whaleAccountMutex = new Mutex(); + + this.logger = createTestLogger(); } selectWhaleAccount(accIndex?: number): { account: Account; accountWallet: NonceManager } { @@ -65,8 +70,8 @@ abstract class AccountManager implements IAccountManager { async generateAccounts(numberOfAccounts: number, initialBalanceWei = etherToWei("10")): Promise { const { account: whaleAccount, accountWallet: whaleAccountWallet } = this.selectWhaleAccount(); - console.log( - `Generating accounts: chainId=${this.chainId} numberOfAccounts=${numberOfAccounts} whaleAccount=${whaleAccount.address}`, + this.logger.debug( + `Generating accounts... chainId=${this.chainId} numberOfAccounts=${numberOfAccounts} whaleAccount=${whaleAccount.address}`, ); const accounts: Account[] = []; @@ -88,13 +93,13 @@ abstract class AccountManager implements IAccountManager { const release = await this.whaleAccountMutex.acquire(); try { const transactionResponse = await whaleAccountWallet.sendTransaction(tx); - console.log( - `Transaction sent: newAccount=${newAccount.address} txHash=${transactionResponse.hash} whaleAccount=${whaleAccount.address}`, + this.logger.debug( + `Transaction sent. newAccount=${newAccount.address} txHash=${transactionResponse.hash} whaleAccount=${whaleAccount.address}`, ); transactionResponses.push(transactionResponse); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { - console.error(`Failed to fund account ${newAccount.address}: ${error.message}`); + logger.error(`Failed to fund account. address=${newAccount.address} error=${error.message}`); whaleAccountWallet.reset(); } finally { release(); @@ -103,8 +108,8 @@ abstract class AccountManager implements IAccountManager { await Promise.all(transactionResponses.map((tx) => tx.wait())); - console.log( - `Accounts funded: newAccounts=${accounts.map((account) => account.address).join(",")} balance=${initialBalanceWei.toString()} wei`, + this.logger.debug( + `Accounts funded. newAccounts=${accounts.map((account) => account.address).join(",")} balance=${initialBalanceWei.toString()} wei`, ); return accounts.map((account) => this.getWallet(account)); diff --git a/e2e/src/gas-limit.spec.ts b/e2e/src/gas-limit.spec.ts index 2b967eb0..7799361d 100644 --- a/e2e/src/gas-limit.spec.ts +++ b/e2e/src/gas-limit.spec.ts @@ -42,7 +42,7 @@ describe("Gas limit test suite", () => { // Ok to type assertion here, because txReceipt won't be null if it passed above assertion. const txBlockNumber = txReceipt?.blockNumber; - console.log(`Waiting for ${txBlockNumber} to be finalized...`); + logger.info(`Waiting for ${txBlockNumber} to be finalized...`); const isBlockFinalized = await pollForContractMethodReturnValueExceedTarget( lineaRollupV6.currentL2BlockNumber, @@ -60,13 +60,13 @@ describe("Gas limit test suite", () => { const account = await l2AccountManager.generateAccount(); const lineaRollupV6 = config.getLineaRollupContract(); - console.log(`Target block gas limit: ${targetBlockGasLimit}`); + logger.info(`Target block gas limit: ${targetBlockGasLimit}`); while (!isTargetBlockGasLimitReached) { const txReceipt = await setGasLimit(account); expect(txReceipt?.status).toEqual(1); const blockGasLimit = await getGasLimit(); - console.log("blockGasLimit: ", blockGasLimit); + logger.info("blockGasLimit: ", blockGasLimit); if (blockGasLimit === targetBlockGasLimit) { isTargetBlockGasLimitReached = true; // Ok to type assertion here, because txReceipt won't be null if it passed above assertion. @@ -75,7 +75,7 @@ describe("Gas limit test suite", () => { await wait(1000); } - console.log(`Waiting for ${blockNumberToCheckFinalization} to be finalized...`); + logger.info(`Waiting for ${blockNumberToCheckFinalization} to be finalized...`); const isBlockFinalized = await pollForContractMethodReturnValueExceedTarget( lineaRollupV6.currentL2BlockNumber, diff --git a/e2e/src/l2.spec.ts b/e2e/src/l2.spec.ts index 651424cf..56b6e8e1 100644 --- a/e2e/src/l2.spec.ts +++ b/e2e/src/l2.spec.ts @@ -151,7 +151,7 @@ describe("Layer 2 test suite", () => { shomeiClient.rollupGetZkEVMBlockNumber(), shomeiFrontendClient.rollupGetZkEVMBlockNumber(), ]); - console.log(`shomeiBlock = ${shomeiBlock}, shomeiFrontendBlock = ${shomeiFrontendBlock}`); + logger.debug(`shomeiBlock=${shomeiBlock}, shomeiFrontendBlock=${shomeiFrontendBlock}`); expect(shomeiBlock).toBeGreaterThan(shomeiFrontendBlock); } diff --git a/e2e/src/messaging.spec.ts b/e2e/src/messaging.spec.ts index 722531d4..f17c768d 100644 --- a/e2e/src/messaging.spec.ts +++ b/e2e/src/messaging.spec.ts @@ -1,18 +1,22 @@ import { ethers, Wallet } from "ethers"; import { describe, expect, it } from "@jest/globals"; +import type { Logger } from "winston"; import { config } from "./config/tests-config"; import { encodeFunctionCall, etherToWei, waitForEvents } from "./common/utils"; import { MESSAGE_SENT_EVENT_SIGNATURE } from "./common/constants"; -async function sendL1ToL2Message({ - l1Account, - l2Account, - withCalldata = false, -}: { - l1Account: Wallet; - l2Account: Wallet; - withCalldata: boolean; -}) { +async function sendL1ToL2Message( + logger: Logger, + { + l1Account, + l2Account, + withCalldata = false, + }: { + l1Account: Wallet; + l2Account: Wallet; + withCalldata: boolean; + }, +) { const dummyContract = config.getL2DummyContract(l2Account); const lineaRollup = config.getLineaRollupContract(l1Account); @@ -36,22 +40,25 @@ async function sendL1ToL2Message({ let receipt = await tx.wait(); while (!receipt) { - console.log("Waiting for transaction to be mined..."); + logger.info("Waiting for transaction to be mined..."); receipt = await tx.wait(); } return { tx, receipt }; } -async function sendL2ToL1Message({ - l1Account, - l2Account, - withCalldata = false, -}: { - l1Account: Wallet; - l2Account: Wallet; - withCalldata: boolean; -}) { +async function sendL2ToL1Message( + logger: Logger, + { + l1Account, + l2Account, + withCalldata = false, + }: { + l1Account: Wallet; + l2Account: Wallet; + withCalldata: boolean; + }, +) { const l2Provider = config.getL2Provider(); const dummyContract = config.getL1DummyContract(l1Account); const l2MessageService = config.getL2MessageServiceContract(l2Account); @@ -75,7 +82,7 @@ async function sendL2ToL1Message({ let receipt = await tx.wait(); while (!receipt) { - console.log("Waiting for transaction to be mined..."); + logger.info("Waiting for transaction to be mined..."); receipt = await tx.wait(); } @@ -94,20 +101,20 @@ describe("Messaging test suite", () => { l2AccountManager.generateAccount(), ]); - const { tx, receipt } = await sendL1ToL2Message({ l1Account, l2Account, withCalldata: true }); + const { tx, receipt } = await sendL1ToL2Message(logger, { l1Account, l2Account, withCalldata: true }); 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)}`); + logger.info(`L1 message sent. messageHash=${messageHash} transaction=${JSON.stringify(tx)}`); - console.log("Waiting for MessageClaimed event on L2."); + logger.info("Waiting for MessageClaimed event on L2."); const l2MessageService = config.getL2MessageServiceContract(); const [messageClaimedEvent] = await waitForEvents( l2MessageService, l2MessageService.filters.MessageClaimed(messageHash), ); - console.log(`Message claimed on L2: ${JSON.stringify(messageClaimedEvent)}`); + logger.info(`Message claimed on L2. event=${JSON.stringify(messageClaimedEvent)}`); expect(messageClaimedEvent).toBeDefined(); }, 100_000, @@ -121,19 +128,19 @@ describe("Messaging test suite", () => { l2AccountManager.generateAccount(), ]); - const { tx, receipt } = await sendL1ToL2Message({ l1Account, l2Account, withCalldata: false }); + const { tx, receipt } = await sendL1ToL2Message(logger, { l1Account, l2Account, withCalldata: false }); 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)}`); + logger.info(`L1 message sent. messageHash=${messageHash} transaction=${JSON.stringify(tx)}`); - console.log("Waiting for MessageClaimed event on L2."); + logger.info("Waiting for MessageClaimed event on L2."); const l2MessageService = config.getL2MessageServiceContract(); const [messageClaimedEvent] = await waitForEvents( l2MessageService, l2MessageService.filters.MessageClaimed(messageHash), ); - console.log(`Message claimed on L2: ${JSON.stringify(messageClaimedEvent)}`); + logger.info(`Message claimed on L2. event=${JSON.stringify(messageClaimedEvent)}`); expect(messageClaimedEvent).toBeDefined(); }, 100_000, @@ -148,27 +155,27 @@ describe("Messaging test suite", () => { ]); const lineaRollup = config.getLineaRollupContract(); - const { tx, receipt } = await sendL2ToL1Message({ l1Account, l2Account, withCalldata: true }); + const { tx, receipt } = await sendL2ToL1Message(logger, { l1Account, l2Account, withCalldata: true }); const [messageSentEvent] = receipt.logs.filter((log) => log.topics[0] === MESSAGE_SENT_EVENT_SIGNATURE); const messageHash = messageSentEvent.topics[3]; - console.log(`L2 message sent: messageHash=${messageHash} transaction=${JSON.stringify(tx)}`); + logger.info(`L2 message sent. messageHash=${messageHash} transaction=${JSON.stringify(tx)}`); - console.log(`Waiting for L2MessagingBlockAnchored... with blockNumber=${messageSentEvent.blockNumber}`); + logger.info(`Waiting for L2MessagingBlockAnchored with blockNumber=${messageSentEvent.blockNumber}...`); await waitForEvents( lineaRollup, lineaRollup.filters.L2MessagingBlockAnchored(messageSentEvent.blockNumber), 1_000, ); - console.log("Waiting for MessageClaimed event on L1."); + logger.info("Waiting for MessageClaimed event on L1."); const [messageClaimedEvent] = await waitForEvents( lineaRollup, lineaRollup.filters.MessageClaimed(messageHash), 1_000, ); - console.log(`Message claimed on L1: ${JSON.stringify(messageClaimedEvent)}`); + logger.info(`Message claimed on L1. event=${JSON.stringify(messageClaimedEvent)}`); expect(messageClaimedEvent).toBeDefined(); }, 150_000, @@ -183,27 +190,27 @@ describe("Messaging test suite", () => { ]); const lineaRollup = config.getLineaRollupContract(); - const { tx, receipt } = await sendL2ToL1Message({ l1Account, l2Account, withCalldata: false }); + const { tx, receipt } = await sendL2ToL1Message(logger, { l1Account, l2Account, withCalldata: false }); const [messageSentEvent] = receipt.logs.filter((log) => log.topics[0] === MESSAGE_SENT_EVENT_SIGNATURE); const messageHash = messageSentEvent.topics[3]; - console.log(`L2 message sent: messageHash=${messageHash} transaction=${JSON.stringify(tx)}`); + logger.info(`L2 message sent. messageHash=${messageHash} transaction=${JSON.stringify(tx)}`); - console.log(`Waiting for L2MessagingBlockAnchored... with blockNumber=${messageSentEvent.blockNumber}`); + logger.info(`Waiting for L2MessagingBlockAnchored with blockNumber=${messageSentEvent.blockNumber}...`); await waitForEvents( lineaRollup, lineaRollup.filters.L2MessagingBlockAnchored(messageSentEvent.blockNumber), 1_000, ); - console.log("Waiting for MessageClaimed event on L1."); + logger.info("Waiting for MessageClaimed event on L1."); const [messageClaimedEvent] = await waitForEvents( lineaRollup, lineaRollup.filters.MessageClaimed(messageHash), 1_000, ); - console.log(`Message claimed on L1: ${JSON.stringify(messageClaimedEvent)}`); + logger.info(`Message claimed on L1. event=${JSON.stringify(messageClaimedEvent)}`); expect(messageClaimedEvent).toBeDefined(); }, 150_000, diff --git a/e2e/src/restart.spec.ts b/e2e/src/restart.spec.ts index 8b347a72..d840f92e 100644 --- a/e2e/src/restart.spec.ts +++ b/e2e/src/restart.spec.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from "@jest/globals"; +import type { Logger } from "winston"; import { execDockerCommand, waitForEvents, @@ -13,19 +14,19 @@ let testsWaitingForRestart = 0; const TOTAL_TESTS_WAITING = 2; let coordinatorHasRestarted = false; -async function waitForCoordinatorRestart() { +async function waitForCoordinatorRestart(logger: Logger) { testsWaitingForRestart += 1; while (testsWaitingForRestart < TOTAL_TESTS_WAITING) { - console.log("Both tests have reached the restart point. Restarting coordinator..."); + logger.info("Both tests have reached the restart point. Restarting coordinator..."); await wait(1_000); if (!coordinatorHasRestarted) { coordinatorHasRestarted = true; try { await execDockerCommand("restart", "coordinator"); - console.log("Coordinator restarted."); + logger.info("Coordinator restarted."); return; } catch (error) { - console.error("Failed to restart coordinator:", error); + logger.error(`Failed to restart coordinator: ${error}`); throw error; } } @@ -39,7 +40,7 @@ describe("Coordinator restart test suite", () => { "When the coordinator restarts it should resume blob submission and finalization", async () => { if (process.env.TEST_ENV !== "local") { - console.log("Skipping test because it's not running on a local environment."); + logger.info("Skipping test because it's not running on a local environment."); return; } const lineaRollup = config.getLineaRollupContract(); @@ -58,11 +59,11 @@ describe("Coordinator restart test suite", () => { expect(lastDataSubmittedEventBeforeRestart.blockNumber).toBeGreaterThan(0n); expect(lastDataFinalizedEventsBeforeRestart.args.endBlockNumber).toBeGreaterThan(0n); - await waitForCoordinatorRestart(); + await waitForCoordinatorRestart(logger); const currentBlockNumberAfterRestart = await l1Provider.getBlockNumber(); - console.log("Waiting for DataSubmittedV3 event after coordinator restart..."); + logger.info("Waiting for DataSubmittedV3 event after coordinator restart..."); const [dataSubmittedV3EventAfterRestart] = await waitForEvents( lineaRollup, lineaRollup.filters.DataSubmittedV3(), @@ -71,9 +72,9 @@ describe("Coordinator restart test suite", () => { "latest", async (events) => events.filter((event) => event.blockNumber > lastDataSubmittedEventBeforeRestart.blockNumber), ); - console.log(`New DataSubmittedV3 event found: event=${JSON.stringify(dataSubmittedV3EventAfterRestart)}`); + logger.info(`New DataSubmittedV3 event found. event=${JSON.stringify(dataSubmittedV3EventAfterRestart)}`); - console.log("Waiting for DataFinalized event after coordinator restart..."); + logger.info("Waiting for DataFinalized event after coordinator restart..."); const [dataFinalizedEventAfterRestart] = await waitForEvents( lineaRollup, lineaRollup.filters.DataFinalizedV3(), @@ -85,7 +86,7 @@ describe("Coordinator restart test suite", () => { (event) => event.args.endBlockNumber > lastDataFinalizedEventsBeforeRestart.args.endBlockNumber, ), ); - console.log(`New DataFinalized event found: event=${JSON.stringify(dataFinalizedEventAfterRestart)}`); + logger.info(`New DataFinalized event found. event=${JSON.stringify(dataFinalizedEventAfterRestart)}`); expect(dataFinalizedEventAfterRestart.args.endBlockNumber).toBeGreaterThan( lastDataFinalizedEventsBeforeRestart.args.endBlockNumber, @@ -98,7 +99,7 @@ describe("Coordinator restart test suite", () => { "When the coordinator restarts it should resume anchoring", async () => { if (process.env.TEST_ENV !== "local") { - console.log("Skipping test because it's not running on a local environment."); + logger.info("Skipping test because it's not running on a local environment."); return; } @@ -144,7 +145,7 @@ describe("Coordinator restart test suite", () => { // Wait for L2 Anchoring const lastNewL1MessageNumber = l1Messages.slice(-1)[0].messageNumber; - console.log(`Waiting L1->L2 anchoring messageNumber=${lastNewL1MessageNumber}`); + logger.info(`Waiting for L1->L2 anchoring. messageNumber=${lastNewL1MessageNumber}`); await waitForEvents( l2MessageService, l2MessageService.filters.RollingHashUpdated(), @@ -157,7 +158,7 @@ describe("Coordinator restart test suite", () => { ); // Restart Coordinator - await waitForCoordinatorRestart(); + await waitForCoordinatorRestart(logger); const l1Fees = await l1Provider.getFeeData(); // Send more messages L1 -> L2 @@ -188,8 +189,8 @@ describe("Coordinator restart test suite", () => { // Wait for messages to be anchored on L2 const lastNewL1MessageNumberAfterRestart = l1MessagesAfterRestart.slice(-1)[0].messageNumber; - console.log( - `Waiting L1->L2 anchoring after coordinator restart messageNumber=${lastNewL1MessageNumberAfterRestart}`, + logger.info( + `Waiting for L1->L2 anchoring after coordinator restart. messageNumber=${lastNewL1MessageNumberAfterRestart}`, ); const [rollingHashUpdatedEventAfterRestart] = await waitForEvents( l2MessageService, diff --git a/e2e/src/submission-finalization.spec.ts b/e2e/src/submission-finalization.spec.ts index 1ece48d9..2059f190 100644 --- a/e2e/src/submission-finalization.spec.ts +++ b/e2e/src/submission-finalization.spec.ts @@ -21,7 +21,7 @@ describe("Submission and finalization test suite", () => { const l1MessageSender = new NonceManager(await l1AccountManager.generateAccount()); const lineaRollup = config.getLineaRollupContract(); - console.log("Sending messages on L1"); + logger.info("Sending messages on L1"); // Send L1 messages const l1MessagesPromises = []; @@ -45,7 +45,7 @@ describe("Submission and finalization test suite", () => { const l1Receipts = await Promise.all(l1MessagesPromises); - console.log("Messages sent on L1."); + logger.info("Messages sent on L1."); // Extract message events const l1Messages = getMessageSentEventFromLogs(lineaRollup, l1Receipts); @@ -65,7 +65,7 @@ describe("Submission and finalization test suite", () => { // Wait for the last L1->L2 message to be anchored on L2 const lastNewL1MessageNumber = l1Messages.slice(-1)[0].messageNumber; - console.log("Waiting for the anchoring using rolling hash..."); + logger.info("Waiting for the anchoring using rolling hash..."); const [rollingHashUpdatedEvent] = await waitForEvents( l2MessageService, l2MessageService.filters.RollingHashUpdated(), @@ -82,7 +82,7 @@ describe("Submission and finalization test suite", () => { expect(lastNewMessageRollingHash).toEqual(rollingHashUpdatedEvent.args.rollingHash); expect(lastAnchoredL1MessageNumber).toEqual(rollingHashUpdatedEvent.args.messageNumber); - console.log("New anchoring using rolling hash done."); + logger.info("New anchoring using rolling hash done."); }, 150_000, ); @@ -94,10 +94,10 @@ describe("Submission and finalization test suite", () => { const currentL2BlockNumber = await lineaRollupV6.currentL2BlockNumber(); - console.log("Waiting for DataSubmittedV3 used to finalize with proof..."); + logger.info("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..."); + logger.info("Waiting for the first DataFinalizedV3 event with proof..."); const [dataFinalizedEvent] = await waitForEvents( lineaRollupV6, lineaRollupV6.filters.DataFinalizedV3(currentL2BlockNumber + 1n), @@ -112,7 +112,7 @@ describe("Submission and finalization test suite", () => { expect(lastBlockFinalized).toBeGreaterThanOrEqual(dataFinalizedEvent.args.endBlockNumber); expect(newStateRootHash).toEqual(dataFinalizedEvent.args.finalStateRootHash); - console.log("Finalization with proof done."); + logger.info("Finalization with proof done."); }, 150_000, ); @@ -122,12 +122,12 @@ describe("Submission and finalization test suite", () => { async () => { const sequencerEndpoint = config.getSequencerEndpoint(); if (!sequencerEndpoint) { - console.log('Skipped the "Check L2 safe/finalized tag update on sequencer" test'); + logger.info('Skipped the "Check L2 safe/finalized tag update on sequencer" test'); return; } const lastFinalizedL2BlockNumberOnL1 = 0; - console.log(`lastFinalizedL2BlockNumberOnL1=${lastFinalizedL2BlockNumberOnL1}`); + logger.debug(`lastFinalizedL2BlockNumberOnL1=${lastFinalizedL2BlockNumberOnL1}`); let safeL2BlockNumber = -1, finalizedL2BlockNumber = -1; @@ -142,12 +142,12 @@ describe("Submission and finalization test suite", () => { await wait(1_000); } - console.log(`safeL2BlockNumber=${safeL2BlockNumber} finalizedL2BlockNumber=${finalizedL2BlockNumber}`); + logger.debug(`safeL2BlockNumber=${safeL2BlockNumber} finalizedL2BlockNumber=${finalizedL2BlockNumber}`); expect(safeL2BlockNumber).toBeGreaterThanOrEqual(lastFinalizedL2BlockNumberOnL1); expect(finalizedL2BlockNumber).toBeGreaterThanOrEqual(lastFinalizedL2BlockNumberOnL1); - console.log("L2 safe/finalized tag update on sequencer done."); + logger.info("L2 safe/finalized tag update on sequencer done."); }, 150_000, ); diff --git a/e2e/src/transaction-exclusion.spec.ts b/e2e/src/transaction-exclusion.spec.ts index d3f75ef3..7f53bfa3 100644 --- a/e2e/src/transaction-exclusion.spec.ts +++ b/e2e/src/transaction-exclusion.spec.ts @@ -30,11 +30,11 @@ describe("Transaction exclusion test suite", () => { await l2AccountLocal.sendTransaction(txRequest); } catch (err) { // This shall return error with traces limit overflow - console.debug(`sendTransaction expected err: ${JSON.stringify(err)}`); + logger.debug(`sendTransaction expected err: ${JSON.stringify(err)}`); } expect(rejectedTxHash).toBeDefined(); - console.log(`rejectedTxHash (RPC): ${rejectedTxHash}`); + logger.debug(`Transaction rejected as expected (RPC). transactionHash=${rejectedTxHash}`); let getResponse; do { @@ -60,7 +60,7 @@ describe("Transaction exclusion test suite", () => { // This shall be rejected by sequencer due to traces module limit overflow const tx = await testContract!.connect(l2AccountLocal).testAddmod(13000, 31); const rejectedTxHash = tx.hash; - console.log(`rejectedTxHash (SEQUENCER): ${rejectedTxHash}`); + logger.debug(`Transaction rejected as expected (SEQUENCER). transactionHash=${rejectedTxHash}`); let getResponse; do { diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json index be4ae3d2..f45a3edf 100644 --- a/e2e/tsconfig.json +++ b/e2e/tsconfig.json @@ -18,5 +18,6 @@ "path": "../sdk" } ], + "include": ["**/*.ts"], "exclude": ["node_modules", "dist"], } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 852d395c..42db2915 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -46,7 +46,7 @@ importers: dependencies: '@consensys/linea-sdk': specifier: 0.3.0 - version: 0.3.0(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(utf-8-validate@5.0.10) + version: 0.3.0(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(utf-8-validate@5.0.10) '@headlessui/react': specifier: 2.1.9 version: 2.1.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -134,7 +134,7 @@ importers: version: 8.1.0(typescript@5.4.5) '@synthetixio/synpress': specifier: 4.0.0-alpha.7 - version: 4.0.0-alpha.7(@playwright/test@1.45.3)(bufferutil@4.0.8)(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.22.4) + version: 4.0.0-alpha.7(@playwright/test@1.45.3)(bufferutil@4.0.8)(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.22.4) '@types/fs-extra': specifier: 11.0.4 version: 11.0.4 @@ -158,16 +158,16 @@ importers: version: 14.2.15(eslint@8.57.0)(typescript@5.4.5) eslint-plugin-tailwindcss: specifier: 3.17.4 - version: 3.17.4(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))) + version: 3.17.4(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))) postcss: specifier: 8.4.47 version: 8.4.47 tailwind-scrollbar: specifier: 3.1.0 - version: 3.1.0(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))) + version: 3.1.0(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))) tailwindcss: specifier: 3.4.13 - version: 3.4.13(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)) + version: 3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)) contracts: dependencies: @@ -263,8 +263,6 @@ importers: specifier: 17.7.2 version: 17.7.2 - contracts/lib/forge-std: {} - e2e: devDependencies: '@jest/globals': @@ -300,6 +298,9 @@ importers: typechain: specifier: 8.3.2 version: 8.3.2(typescript@5.4.5) + winston: + specifier: 3.17.0 + version: 3.17.0 operations: dependencies: @@ -6647,10 +6648,6 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} - logform@2.6.1: - resolution: {integrity: sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==} - engines: {node: '>= 12.0.0'} - logform@2.7.0: resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} engines: {node: '>= 12.0.0'} @@ -9475,18 +9472,10 @@ packages: resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} engines: {node: '>=8'} - winston-transport@4.8.0: - resolution: {integrity: sha512-qxSTKswC6llEMZKgCQdaWgDuMJQnhuvF5f2Nk3SNXc4byfQ+voo2mX1Px9dkNOuR8p0KAjfPG29PuYUSIb+vSA==} - engines: {node: '>= 12.0.0'} - winston-transport@4.9.0: resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} engines: {node: '>= 12.0.0'} - winston@3.13.0: - resolution: {integrity: sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==} - engines: {node: '>= 12.0.0'} - winston@3.17.0: resolution: {integrity: sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==} engines: {node: '>= 12.0.0'} @@ -10728,7 +10717,7 @@ snapshots: '@colors/colors@1.6.0': {} - '@consensys/linea-sdk@0.3.0(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(utf-8-validate@5.0.10)': + '@consensys/linea-sdk@0.3.0(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(utf-8-validate@5.0.10)': dependencies: better-sqlite3: 9.6.0 class-validator: 0.14.1 @@ -10736,9 +10725,9 @@ snapshots: ethers: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) lru-cache: 10.2.2 pg: 8.11.3 - typeorm: 0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)) - typeorm-naming-strategies: 4.1.0(typeorm@0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))) - winston: 3.13.0 + typeorm: 0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)) + typeorm-naming-strategies: 4.1.0(typeorm@0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))) + winston: 3.17.0 transitivePeerDependencies: - '@google-cloud/spanner' - '@sap/hana-client' @@ -13040,7 +13029,7 @@ snapshots: - utf-8-validate - zod - '@synthetixio/synpress-cache@0.0.1-alpha.7(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5)': + '@synthetixio/synpress-cache@0.0.1-alpha.7(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5)': dependencies: axios: 1.6.7 chalk: 5.3.0 @@ -13051,7 +13040,7 @@ snapshots: gradient-string: 2.0.2 playwright-core: 1.45.3 progress: 2.0.3 - tsup: 8.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5) + tsup: 8.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5) unzipper: 0.10.14 zod: 3.22.4 transitivePeerDependencies: @@ -13067,10 +13056,10 @@ snapshots: dependencies: '@playwright/test': 1.45.3 - '@synthetixio/synpress-metamask@0.0.1-alpha.7(@playwright/test@1.45.3)(bufferutil@4.0.8)(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10)': + '@synthetixio/synpress-metamask@0.0.1-alpha.7(@playwright/test@1.45.3)(bufferutil@4.0.8)(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10)': dependencies: '@playwright/test': 1.45.3 - '@synthetixio/synpress-cache': 0.0.1-alpha.7(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5) + '@synthetixio/synpress-cache': 0.0.1-alpha.7(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5) '@synthetixio/synpress-core': 0.0.1-alpha.7(@playwright/test@1.45.3) '@viem/anvil': 0.0.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) fs-extra: 11.2.0 @@ -13087,13 +13076,13 @@ snapshots: - typescript - utf-8-validate - '@synthetixio/synpress@4.0.0-alpha.7(@playwright/test@1.45.3)(bufferutil@4.0.8)(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@synthetixio/synpress@4.0.0-alpha.7(@playwright/test@1.45.3)(bufferutil@4.0.8)(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.22.4)': dependencies: '@playwright/test': 1.45.3 '@synthetixio/ethereum-wallet-mock': 0.0.1-alpha.7(@playwright/test@1.45.3)(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.22.4) - '@synthetixio/synpress-cache': 0.0.1-alpha.7(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5) + '@synthetixio/synpress-cache': 0.0.1-alpha.7(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5) '@synthetixio/synpress-core': 0.0.1-alpha.7(@playwright/test@1.45.3) - '@synthetixio/synpress-metamask': 0.0.1-alpha.7(@playwright/test@1.45.3)(bufferutil@4.0.8)(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10) + '@synthetixio/synpress-metamask': 0.0.1-alpha.7(@playwright/test@1.45.3)(bufferutil@4.0.8)(playwright-core@1.45.3)(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10) transitivePeerDependencies: - '@microsoft/api-extractor' - '@swc/core' @@ -15973,7 +15962,7 @@ snapshots: debug: 4.3.7(supports-color@8.1.1) enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -15986,7 +15975,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: @@ -16008,7 +15997,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -16081,11 +16070,11 @@ snapshots: string.prototype.matchall: 4.0.11 string.prototype.repeat: 1.0.0 - eslint-plugin-tailwindcss@3.17.4(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))): + eslint-plugin-tailwindcss@3.17.4(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))): dependencies: fast-glob: 3.3.2 postcss: 8.4.47 - tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)) + tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)) eslint-scope@7.2.2: dependencies: @@ -18336,15 +18325,6 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 - logform@2.6.1: - dependencies: - '@colors/colors': 1.6.0 - '@types/triple-beam': 1.3.5 - fecha: 4.2.3 - ms: 2.1.3 - safe-stable-stringify: 2.5.0 - triple-beam: 1.4.1 - logform@2.7.0: dependencies: '@colors/colors': 1.6.0 @@ -19407,13 +19387,13 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.4.47 - postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)): + postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)): dependencies: lilconfig: 3.1.2 yaml: 2.5.1 optionalDependencies: postcss: 8.4.47 - ts-node: 10.9.2(@types/node@20.12.7)(typescript@5.4.5) + ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.4.5) postcss-nested@6.2.0(postcss@8.4.47): dependencies: @@ -20662,11 +20642,11 @@ snapshots: tailwind-merge@2.5.3: {} - tailwind-scrollbar@3.1.0(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))): + tailwind-scrollbar@3.1.0(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))): dependencies: - tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)) + tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)) - tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)): + tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -20685,7 +20665,7 @@ snapshots: postcss: 8.4.47 postcss-import: 15.1.0(postcss@8.4.47) postcss-js: 4.0.1(postcss@8.4.47) - postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)) postcss-nested: 6.2.0(postcss@8.4.47) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -20937,7 +20917,7 @@ snapshots: tsort@0.0.1: {} - tsup@8.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5): + tsup@8.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5): dependencies: bundle-require: 4.2.1(esbuild@0.19.12) cac: 6.7.14 @@ -20947,7 +20927,7 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)) resolve-from: 5.0.0 rollup: 4.24.0 source-map: 0.8.0-beta.0 @@ -21055,9 +21035,9 @@ snapshots: dependencies: typeorm: 0.3.20(better-sqlite3@11.6.0)(pg@8.13.1)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)) - typeorm-naming-strategies@4.1.0(typeorm@0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))): + typeorm-naming-strategies@4.1.0(typeorm@0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5))): dependencies: - typeorm: 0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)) + typeorm: 0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)) typeorm@0.3.20(better-sqlite3@11.6.0)(pg@8.13.1)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)): dependencies: @@ -21083,7 +21063,7 @@ snapshots: transitivePeerDependencies: - supports-color - typeorm@0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)): + typeorm@0.3.20(better-sqlite3@9.6.0)(pg@8.11.3)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.4.5)): dependencies: '@sqltools/formatter': 1.2.5 app-root-path: 3.1.0 @@ -21103,7 +21083,7 @@ snapshots: optionalDependencies: better-sqlite3: 9.6.0 pg: 8.11.3 - ts-node: 10.9.2(@types/node@20.12.7)(typescript@5.4.5) + ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.4.5) transitivePeerDependencies: - supports-color @@ -21675,32 +21655,12 @@ snapshots: dependencies: string-width: 4.2.3 - winston-transport@4.8.0: - dependencies: - logform: 2.6.1 - readable-stream: 4.5.2 - triple-beam: 1.4.1 - winston-transport@4.9.0: dependencies: logform: 2.7.0 readable-stream: 3.6.2 triple-beam: 1.4.1 - winston@3.13.0: - dependencies: - '@colors/colors': 1.6.0 - '@dabh/diagnostics': 2.0.3 - async: 3.2.6 - is-stream: 2.0.1 - logform: 2.6.1 - one-time: 1.0.0 - readable-stream: 3.6.2 - safe-stable-stringify: 2.5.0 - stack-trace: 0.0.10 - triple-beam: 1.4.1 - winston-transport: 4.8.0 - winston@3.17.0: dependencies: '@colors/colors': 1.6.0