mirror of
https://github.com/vacp2p/linea-monorepo.git
synced 2026-01-09 04:08:01 -05:00
Feat/122 Add TokenBridge e2e tests (#210)
* fix: add mutex in account manager to avoid nonce issue * fix: optimize global setup * Limiting number of concurrent traces API requests for the local stack to avoid occasional OOM-s * Limiting number of verticles for Traces API node * Add E2E TokenBridge tests * fixing test and adding concurency * fixing test and adding concurency * fixing test and adding concurency * fixing test and adding concurency * fixing nonce management * deploying l2token for the L2 -> L1 test * adjusting accounts for L2->L1 test * adjusting l2TestContractAddress * use nonce management for L1->L2 test * adjusting the TestERC20 contract and tests * rebasing with fix/133-improve-e2e-tests-performance * fix: update jest config to exit even if there are open handles * Trying out Besu untuned and raising limit per endpoint to 2 for traces * Trying out Besu untuned and raising limit per endpoint to 2 for traces and Shomei node * Using besu untuned for arithmetization as well * Compile once and parallelise setRemoteTokenBridge * feat: deploy smart contracts from artifacts + change e2e tests setup * fix: update pnpm * fix: remove compile contracts gradle task * fix: remove compileContracts gradle task * fix: refactor genesis generator dockerfile + downgrade l1-el-node besu version * fix: move abi from e2e folder to contract folder + refactor contracts deployments scripts * feat: add deployment script from artifacts for LineaRollupV6 * update pnpm version in get-started.md * fix: update console log in deployment scripts * fix: update besu version + fix deployment scripts * correct addresses * fix import * use abi and bytecode for deployments * use upgradable beacon for BridgedToken ABI deploys * use saved abi and bytecode for TestERC20 deploy * correct deployBridgedTokenAndTokenBridge casing * optimize token bridge e2e calls * use explicit message event data * use precomputed nonces for e2e stack --------- Co-authored-by: VGau <victorien.gauch@consensys.net> Co-authored-by: Victorien Gauch <85494462+VGau@users.noreply.github.com> Co-authored-by: Roman <4833306+Filter94@users.noreply.github.com> Co-authored-by: thedarkjester <grant.southey@consensys.net> Co-authored-by: The Dark Jester <thedarkjester@users.noreply.github.com>
This commit is contained in:
211
e2e/src/bridge-tokens.spec.ts
Normal file
211
e2e/src/bridge-tokens.spec.ts
Normal file
@@ -0,0 +1,211 @@
|
||||
import { ethers } from "ethers";
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { config } from "./config/tests-config";
|
||||
import { waitForEvents, etherToWei } from "./common/utils";
|
||||
import { MESSAGE_SENT_EVENT_SIGNATURE } from "./common/constants";
|
||||
|
||||
const l1AccountManager = config.getL1AccountManager();
|
||||
const l2AccountManager = config.getL2AccountManager();
|
||||
const bridgeAmount = ethers.parseEther("100");
|
||||
const messageSentEventMessageNumberIndex = 4;
|
||||
const messageSentEventMessageHashIndex = 6;
|
||||
|
||||
describe("Bridge ERC20 Tokens L1 -> L2 and L2 -> L1", () => {
|
||||
it.concurrent("Bridge a token from L1 to L2", async () => {
|
||||
const [l1Account, l2Account] = await Promise.all([
|
||||
l1AccountManager.generateAccount(),
|
||||
l2AccountManager.generateAccount(),
|
||||
]);
|
||||
|
||||
const lineaRollup = config.getLineaRollupContract();
|
||||
const l2MessageService = config.getL2MessageServiceContract();
|
||||
const l1TokenBridge = config.getL1TokenBridgeContract();
|
||||
const l2TokenBridge = config.getL2TokenBridgeContract();
|
||||
const l1Token = config.getL1TokenContract();
|
||||
const l1Provider = config.getL1Provider();
|
||||
|
||||
console.log("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");
|
||||
|
||||
await Promise.all([
|
||||
(
|
||||
await l1Token.connect(l1Account).mint(l1Account.address, bridgeAmount, {
|
||||
nonce: nonce,
|
||||
maxPriorityFeePerGas: l1MaxPriorityFeePerGas,
|
||||
maxFeePerGas: l1MaxFeePerGas,
|
||||
})
|
||||
).wait(),
|
||||
(
|
||||
await l1Token.connect(l1Account).approve(l1TokenBridge.getAddress(), bridgeAmount, {
|
||||
maxPriorityFeePerGas: l1MaxPriorityFeePerGas,
|
||||
maxFeePerGas: l1MaxFeePerGas,
|
||||
nonce: nonce + 1,
|
||||
})
|
||||
).wait(),
|
||||
]);
|
||||
|
||||
const l1TokenBridgeAddress = await l1TokenBridge.getAddress();
|
||||
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());
|
||||
|
||||
console.log("Calling the bridgeToken function on the L1 TokenBridge contract");
|
||||
|
||||
({ maxPriorityFeePerGas: l1MaxPriorityFeePerGas, maxFeePerGas: l1MaxFeePerGas } = await l1Provider.getFeeData());
|
||||
nonce = await l1Provider.getTransactionCount(l1Account.address, "pending");
|
||||
|
||||
const bridgeTokenTx = await l1TokenBridge
|
||||
.connect(l1Account)
|
||||
.bridgeToken(l1TokenAddress, bridgeAmount, l2Account.address, {
|
||||
value: etherToWei("0.01"),
|
||||
maxPriorityFeePerGas: l1MaxPriorityFeePerGas,
|
||||
maxFeePerGas: l1MaxFeePerGas,
|
||||
nonce: nonce,
|
||||
});
|
||||
|
||||
const bridgedTxReceipt = await bridgeTokenTx.wait();
|
||||
|
||||
const sentEventLog = bridgedTxReceipt?.logs.find((log) => log.topics[0] == MESSAGE_SENT_EVENT_SIGNATURE);
|
||||
|
||||
const messageSentEvent = lineaRollup.interface.decodeEventLog(
|
||||
"MessageSent",
|
||||
sentEventLog!.data,
|
||||
sentEventLog!.topics,
|
||||
);
|
||||
|
||||
const l1TokenBalance = await l1Token.balanceOf(l1Account.address);
|
||||
console.log("Token balance of L1 account :", l1TokenBalance.toString());
|
||||
|
||||
expect(l1TokenBalance).toEqual(0n);
|
||||
|
||||
console.log("Waiting for MessageSent event on L1.");
|
||||
|
||||
const messageNumber = messageSentEvent[messageSentEventMessageNumberIndex];
|
||||
const messageHash = messageSentEvent[messageSentEventMessageHashIndex];
|
||||
|
||||
console.log(`Message sent on L1 : messageHash=${messageHash}`);
|
||||
|
||||
console.log("Waiting for anchoring...");
|
||||
|
||||
const [rollingHashUpdatedEvent] = await waitForEvents(
|
||||
l2MessageService,
|
||||
l2MessageService.filters.RollingHashUpdated(),
|
||||
1_000,
|
||||
0,
|
||||
"latest",
|
||||
async (events) => events.filter((event) => event.args.messageNumber >= messageNumber),
|
||||
);
|
||||
expect(rollingHashUpdatedEvent).not.toBeNull();
|
||||
|
||||
const anchoredStatus = await l2MessageService.inboxL1L2MessageStatus(messageHash);
|
||||
|
||||
expect(anchoredStatus).toBeGreaterThan(0);
|
||||
|
||||
console.log(`Message anchored : ${JSON.stringify(rollingHashUpdatedEvent)}`);
|
||||
|
||||
console.log("Waiting for MessageClaimed event on L2...");
|
||||
|
||||
const [claimedEvent] = await waitForEvents(l2MessageService, l2MessageService.filters.MessageClaimed(messageHash));
|
||||
expect(claimedEvent).not.toBeNull();
|
||||
|
||||
const [newTokenDeployed] = await waitForEvents(l2TokenBridge, l2TokenBridge.filters.NewTokenDeployed());
|
||||
expect(newTokenDeployed).not.toBeNull();
|
||||
|
||||
console.log(`Message claimed on L2 : ${JSON.stringify(claimedEvent)}.`);
|
||||
|
||||
const l2Token = config.getL2BridgedTokenContract(newTokenDeployed.args.bridgedToken);
|
||||
|
||||
console.log("Verify the token balance on L2");
|
||||
|
||||
const l2TokenBalance = await l2Token.balanceOf(l2Account.address);
|
||||
console.log("Token balance of L2 account :", l2TokenBalance.toString());
|
||||
|
||||
expect(l2TokenBalance).toEqual(bridgeAmount);
|
||||
});
|
||||
|
||||
it.concurrent("Bridge a token from L2 to L1", async () => {
|
||||
const [l1Account, l2Account] = await Promise.all([
|
||||
l1AccountManager.generateAccount(),
|
||||
l2AccountManager.generateAccount(),
|
||||
]);
|
||||
|
||||
const lineaRollup = config.getLineaRollupContract();
|
||||
const l2MessageService = config.getL2MessageServiceContract();
|
||||
const l1TokenBridge = config.getL1TokenBridgeContract();
|
||||
const l2TokenBridge = config.getL2TokenBridgeContract();
|
||||
const l2Token = config.getL2TokenContract();
|
||||
const l2Provider = config.getL2Provider();
|
||||
|
||||
const { maxPriorityFeePerGas: l2MaxPriorityFeePerGas, maxFeePerGas: l2MaxFeePerGas } =
|
||||
await l2Provider.getFeeData();
|
||||
let nonce = await l2Provider.getTransactionCount(l2Account.address, "pending");
|
||||
|
||||
await Promise.all([
|
||||
(
|
||||
await l2Token.connect(l2Account).mint(l2Account.address, bridgeAmount, {
|
||||
nonce: nonce,
|
||||
maxPriorityFeePerGas: l2MaxPriorityFeePerGas,
|
||||
maxFeePerGas: l2MaxFeePerGas,
|
||||
})
|
||||
).wait(),
|
||||
(
|
||||
await l2Token.connect(l2Account).approve(l2TokenBridge.getAddress(), ethers.parseEther("100"), {
|
||||
maxPriorityFeePerGas: l2MaxPriorityFeePerGas,
|
||||
maxFeePerGas: l2MaxFeePerGas,
|
||||
nonce: nonce + 1,
|
||||
})
|
||||
).wait(),
|
||||
]);
|
||||
|
||||
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));
|
||||
|
||||
console.log("Calling the bridgeToken function on the L2 TokenBridge contract");
|
||||
|
||||
nonce = await l2Provider.getTransactionCount(l2Account.address, "pending");
|
||||
|
||||
const bridgeTokenTx = await l2TokenBridge
|
||||
.connect(l2Account)
|
||||
.bridgeToken(await l2Token.getAddress(), bridgeAmount, l1Account.address, {
|
||||
value: etherToWei("0.01"),
|
||||
maxPriorityFeePerGas: l2MaxPriorityFeePerGas,
|
||||
maxFeePerGas: l2MaxFeePerGas,
|
||||
nonce: nonce,
|
||||
});
|
||||
|
||||
const receipt = await bridgeTokenTx.wait();
|
||||
const sentEventLog = receipt?.logs.find((log) => log.topics[0] == MESSAGE_SENT_EVENT_SIGNATURE);
|
||||
|
||||
const messageSentEvent = l2MessageService.interface.decodeEventLog(
|
||||
"MessageSent",
|
||||
sentEventLog!.data,
|
||||
sentEventLog!.topics,
|
||||
);
|
||||
const messageHash = messageSentEvent[messageSentEventMessageHashIndex];
|
||||
|
||||
console.log("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)}`);
|
||||
|
||||
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");
|
||||
|
||||
const l1BridgedTokenBalance = await l1BridgedToken.balanceOf(l1Account.address);
|
||||
console.log("Token balance of L1 account :", l1BridgedTokenBalance.toString());
|
||||
|
||||
expect(l1BridgedTokenBalance).toEqual(bridgeAmount);
|
||||
});
|
||||
});
|
||||
@@ -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, LineaRollupV5 } from "../typechain";
|
||||
import { L2MessageService, TokenBridge, LineaRollupV5 } from "../typechain";
|
||||
import { PayableOverrides, TypedContractEvent, TypedDeferredTopicFilter, TypedEventLog } from "../typechain/common";
|
||||
import { MessageEvent, SendMessageArgs } from "./types";
|
||||
|
||||
@@ -147,7 +147,10 @@ export async function getBlockByNumberOrBlockTag(rpcUrl: URL, blockTag: BlockTag
|
||||
}
|
||||
}
|
||||
|
||||
export async function getEvents<TContract extends LineaRollupV5 | L2MessageService, TEvent extends TypedContractEvent>(
|
||||
export async function getEvents<
|
||||
TContract extends LineaRollupV5 | L2MessageService | TokenBridge,
|
||||
TEvent extends TypedContractEvent,
|
||||
>(
|
||||
contract: TContract,
|
||||
eventFilter: TypedDeferredTopicFilter<TEvent>,
|
||||
fromBlock?: BlockTag,
|
||||
@@ -168,7 +171,7 @@ export async function getEvents<TContract extends LineaRollupV5 | L2MessageServi
|
||||
}
|
||||
|
||||
export async function waitForEvents<
|
||||
TContract extends LineaRollupV5 | L2MessageService,
|
||||
TContract extends LineaRollupV5 | L2MessageService | TokenBridge,
|
||||
TEvent extends TypedContractEvent,
|
||||
>(
|
||||
contract: TContract,
|
||||
|
||||
@@ -9,10 +9,18 @@ declare global {
|
||||
}
|
||||
|
||||
export default async (): Promise<void> => {
|
||||
const l1JsonRpcProvider = config.getL1Provider();
|
||||
const l1AccountManager = config.getL1AccountManager();
|
||||
const l2AccountManager = config.getL2AccountManager();
|
||||
|
||||
const account = config.getL1AccountManager().whaleAccount(0);
|
||||
const l2Account = config.getL2AccountManager().whaleAccount(0);
|
||||
const lineaRollup = config.getLineaRollupContract(account);
|
||||
const l1JsonRpcProvider = config.getL1Provider();
|
||||
|
||||
const l1TokenBridge = config.getL1TokenBridgeContract();
|
||||
const l2TokenBridge = config.getL2TokenBridgeContract();
|
||||
const l1SecurityCouncil = l1AccountManager.whaleAccount(3);
|
||||
const l2SecurityCouncil = l2AccountManager.whaleAccount(3);
|
||||
|
||||
const [l1AccountNonce, l2AccountNonce, { maxPriorityFeePerGas, maxFeePerGas }] = await Promise.all([
|
||||
account.getNonce(),
|
||||
@@ -37,6 +45,8 @@ export default async (): Promise<void> => {
|
||||
nonce: l1AccountNonce + 1,
|
||||
})
|
||||
).wait(),
|
||||
(await l1TokenBridge.connect(l1SecurityCouncil).setRemoteTokenBridge(await l2TokenBridge.getAddress())).wait(),
|
||||
(await l2TokenBridge.connect(l2SecurityCouncil).setRemoteTokenBridge(await l1TokenBridge.getAddress())).wait(),
|
||||
]);
|
||||
|
||||
console.log(`L1 Dummy contract deployed at address: ${await dummyContract.getAddress()}`);
|
||||
|
||||
@@ -26,6 +26,8 @@ const config: Config = {
|
||||
rpcUrl: L1_RPC_URL,
|
||||
chainId: L1_CHAIN_ID,
|
||||
lineaRollupAddress: "0x2A5CDCfc38856e2590E9Bd32F54Fa348e5De5f48",
|
||||
tokenBridgeAddress: "",
|
||||
l1TokenAddress: "",
|
||||
accountManager: new EnvironmentBasedAccountManager(
|
||||
new ethers.JsonRpcProvider(L1_RPC_URL.toString()),
|
||||
L1_WHALE_ACCOUNTS,
|
||||
@@ -37,6 +39,8 @@ const config: Config = {
|
||||
rpcUrl: L2_RPC_URL,
|
||||
chainId: L2_CHAIN_ID,
|
||||
l2MessageServiceAddress: "0x33bf916373159A8c1b54b025202517BfDbB7863D",
|
||||
tokenBridgeAddress: "",
|
||||
l2TokenAddress: "",
|
||||
l2TestContractAddress: "",
|
||||
accountManager: new EnvironmentBasedAccountManager(
|
||||
new ethers.JsonRpcProvider(L2_RPC_URL.toString()),
|
||||
|
||||
@@ -16,7 +16,9 @@ const config: Config = {
|
||||
rpcUrl: L1_RPC_URL,
|
||||
chainId: 31648428,
|
||||
lineaRollupAddress: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
|
||||
dummyContractAddress: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
|
||||
dummyContractAddress: "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
|
||||
tokenBridgeAddress: "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6",
|
||||
l1TokenAddress: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
|
||||
accountManager: new GenesisBasedAccountManager(
|
||||
new ethers.JsonRpcProvider(L1_RPC_URL.toString()),
|
||||
path.resolve(
|
||||
@@ -30,8 +32,10 @@ const config: Config = {
|
||||
besuNodeRpcUrl: L2_BESU_NODE_RPC_URL,
|
||||
chainId: 1337,
|
||||
l2MessageServiceAddress: "0xe537D669CA013d86EBeF1D64e40fC74CADC91987",
|
||||
l2TestContractAddress: "0xeB0b0a14F92e3BA35aEF3a2B6A24D7ED1D11631B",
|
||||
dummyContractAddress: "0x2f6dAaF8A81AB675fbD37Ca6Ed5b72cf86237453",
|
||||
l2TestContractAddress: "0x997FC3aF1F193Cbdc013060076c67A13e218980e",
|
||||
dummyContractAddress: "0xE4392c8ecC46b304C83cDB5edaf742899b1bda93",
|
||||
tokenBridgeAddress: "0x5C95Bcd50E6D1B4E3CDC478484C9030Ff0a7D493",
|
||||
l2TokenAddress: "0xCC1B08B17301e090cbb4c1F5598Cbaa096d591FB",
|
||||
accountManager: new GenesisBasedAccountManager(
|
||||
new ethers.JsonRpcProvider(L2_RPC_URL.toString()),
|
||||
path.resolve(
|
||||
|
||||
@@ -25,6 +25,8 @@ const config: Config = {
|
||||
rpcUrl: L1_RPC_URL,
|
||||
chainId: L1_CHAIN_ID,
|
||||
lineaRollupAddress: "0xB218f8A4Bc926cF1cA7b3423c154a0D627Bdb7E5",
|
||||
tokenBridgeAddress: "0x5A0a48389BB0f12E5e017116c1105da97E129142",
|
||||
l1TokenAddress: "",
|
||||
accountManager: new EnvironmentBasedAccountManager(
|
||||
new ethers.JsonRpcProvider(L1_RPC_URL.toString()),
|
||||
L1_WHALE_ACCOUNTS,
|
||||
@@ -36,6 +38,8 @@ const config: Config = {
|
||||
rpcUrl: L2_RPC_URL,
|
||||
chainId: L2_CHAIN_ID,
|
||||
l2MessageServiceAddress: "0x971e727e956690b9957be6d51Ec16E73AcAC83A7",
|
||||
tokenBridgeAddress: "0x93DcAdf238932e6e6a85852caC89cBd71798F463",
|
||||
l2TokenAddress: "",
|
||||
l2TestContractAddress: "",
|
||||
accountManager: new EnvironmentBasedAccountManager(
|
||||
new ethers.JsonRpcProvider(L2_RPC_URL.toString()),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { AbstractSigner, JsonRpcProvider, Wallet } from "ethers";
|
||||
import { Config, L2Config, LocalL2Config } from "./types";
|
||||
import {
|
||||
BridgedToken,
|
||||
BridgedToken__factory,
|
||||
DummyContract,
|
||||
DummyContract__factory,
|
||||
L2MessageService,
|
||||
@@ -9,6 +11,10 @@ import {
|
||||
LineaRollupV5__factory,
|
||||
TestContract,
|
||||
TestContract__factory,
|
||||
TestERC20,
|
||||
TestERC20__factory,
|
||||
TokenBridge,
|
||||
TokenBridge__factory,
|
||||
} from "../../typechain";
|
||||
import { AccountManager } from "./accounts/account-manager";
|
||||
|
||||
@@ -99,6 +105,71 @@ export default class TestSetup {
|
||||
return l2MessageService;
|
||||
}
|
||||
|
||||
public getL1TokenBridgeContract(signer?: Wallet): TokenBridge {
|
||||
const l1TokenBridge: TokenBridge = TokenBridge__factory.connect(
|
||||
this.config.L1.tokenBridgeAddress,
|
||||
this.getL1Provider(),
|
||||
);
|
||||
|
||||
if (signer) {
|
||||
return l1TokenBridge.connect(signer);
|
||||
}
|
||||
|
||||
return l1TokenBridge;
|
||||
}
|
||||
|
||||
public getL2TokenBridgeContract(signer?: Wallet): TokenBridge {
|
||||
const l2TokenBridge: TokenBridge = TokenBridge__factory.connect(
|
||||
this.config.L2.tokenBridgeAddress,
|
||||
this.getL2Provider(),
|
||||
);
|
||||
|
||||
if (signer) {
|
||||
return l2TokenBridge.connect(signer);
|
||||
}
|
||||
|
||||
return l2TokenBridge;
|
||||
}
|
||||
|
||||
public getL1TokenContract(signer?: Wallet): TestERC20 {
|
||||
const l1Token: TestERC20 = TestERC20__factory.connect(this.config.L1.l1TokenAddress, this.getL1Provider());
|
||||
|
||||
if (signer) {
|
||||
return l1Token.connect(signer);
|
||||
}
|
||||
|
||||
return l1Token;
|
||||
}
|
||||
|
||||
public getL2TokenContract(signer?: Wallet): TestERC20 {
|
||||
const l2Token: TestERC20 = TestERC20__factory.connect(this.config.L2.l2TokenAddress, this.getL2Provider());
|
||||
|
||||
if (signer) {
|
||||
return l2Token.connect(signer);
|
||||
}
|
||||
|
||||
return l2Token;
|
||||
}
|
||||
|
||||
public getL1BridgedTokenContract(bridgedTokenAddress: string, signer?: Wallet): BridgedToken {
|
||||
const l1BridgedToken: BridgedToken = BridgedToken__factory.connect(bridgedTokenAddress, this.getL1Provider());
|
||||
|
||||
if (signer) {
|
||||
return l1BridgedToken.connect(signer);
|
||||
}
|
||||
|
||||
return l1BridgedToken;
|
||||
}
|
||||
|
||||
public getL2BridgedTokenContract(bridgedTokenAddress: string, signer?: Wallet): BridgedToken {
|
||||
const l2BridgedToken: BridgedToken = BridgedToken__factory.connect(bridgedTokenAddress, this.getL2Provider());
|
||||
|
||||
if (signer) {
|
||||
return l2BridgedToken.connect(signer);
|
||||
}
|
||||
|
||||
return l2BridgedToken;
|
||||
}
|
||||
public getL1DummyContract(signer?: Wallet): DummyContract {
|
||||
const dummyContract = DummyContract__factory.connect(this.config.L1.dummyContractAddress, this.getL1Provider());
|
||||
|
||||
|
||||
@@ -9,11 +9,20 @@ export type BaseConfig = {
|
||||
|
||||
export type L1Config = BaseConfig & {
|
||||
lineaRollupAddress: string;
|
||||
tokenBridgeAddress: string;
|
||||
l1TokenAddress: string;
|
||||
};
|
||||
|
||||
export type BaseL2Config = BaseConfig & {
|
||||
l2MessageServiceAddress: string;
|
||||
l2TestContractAddress: string;
|
||||
l2TestContractAddress?: string;
|
||||
besuNodeRpcUrl?: URL;
|
||||
tokenBridgeAddress: string;
|
||||
l2TokenAddress: string;
|
||||
shomeiEndpoint?: URL;
|
||||
shomeiFrontendEndpoint?: URL;
|
||||
sequencerEndpoint?: URL;
|
||||
transactionExclusionEndpoint?: URL;
|
||||
};
|
||||
|
||||
export type LocalL2Config = BaseL2Config & {
|
||||
|
||||
@@ -7,6 +7,8 @@ import { TRANSACTION_CALLDATA_LIMIT } from "./common/constants";
|
||||
const l2AccountManager = config.getL2AccountManager();
|
||||
|
||||
describe("Layer 2 test suite", () => {
|
||||
const l2Provider = config.getL2Provider();
|
||||
|
||||
it.concurrent("Should revert if transaction data size is above the limit", async () => {
|
||||
const account = await l2AccountManager.generateAccount();
|
||||
const dummyContract = config.getL2DummyContract(account);
|
||||
@@ -19,8 +21,14 @@ describe("Layer 2 test suite", () => {
|
||||
it.concurrent("Should succeed if transaction data size is below the limit", async () => {
|
||||
const account = await l2AccountManager.generateAccount();
|
||||
const dummyContract = config.getL2DummyContract(account);
|
||||
const nonce = await l2Provider.getTransactionCount(account.address, "pending");
|
||||
const { maxPriorityFeePerGas, maxFeePerGas } = await l2Provider.getFeeData();
|
||||
|
||||
const tx = await dummyContract.connect(account).setPayload(ethers.randomBytes(1000));
|
||||
const tx = await dummyContract.connect(account).setPayload(ethers.randomBytes(1000), {
|
||||
nonce: nonce,
|
||||
maxPriorityFeePerGas: maxPriorityFeePerGas,
|
||||
maxFeePerGas: maxFeePerGas,
|
||||
});
|
||||
|
||||
const receipt = await tx.wait();
|
||||
expect(receipt?.status).toEqual(1);
|
||||
|
||||
Reference in New Issue
Block a user