mirror of
https://github.com/vacp2p/linea-monorepo.git
synced 2026-01-09 20:27:58 -05:00
feat: use linea_estimateGas instead of getFeeData for all L2 transact… (#660)
* feat: use linea_estimateGas instead of getFeeData for all L2 transactions * feat: use linea_estimateGas instead of getFeeData for L2 transactionswith call data and enable json-rpc-pricing-propagation * feat: set DISABLE_JSON_RPC_PRICING_PROPAGATION of coordinator as false for e2e ci
This commit is contained in:
4
Makefile
4
Makefile
@@ -75,13 +75,13 @@ start-env-with-tracing-v1:
|
||||
make start-env COMPOSE_FILE=docker/compose-tracing-v1.yml LINEA_PROTOCOL_CONTRACTS_ONLY=true
|
||||
|
||||
start-env-with-tracing-v1-ci:
|
||||
make start-env COMPOSE_FILE=docker/compose-tracing-v1-ci-extension.yml
|
||||
make start-env COMPOSE_FILE=docker/compose-tracing-v1-ci-extension.yml DISABLE_JSON_RPC_PRICING_PROPAGATION=false
|
||||
|
||||
start-env-with-tracing-v2:
|
||||
make start-env COMPOSE_FILE=docker/compose-tracing-v2.yml LINEA_PROTOCOL_CONTRACTS_ONLY=true
|
||||
|
||||
start-env-with-tracing-v2-ci:
|
||||
make start-env COMPOSE_FILE=docker/compose-tracing-v2-ci-extension.yml
|
||||
make start-env COMPOSE_FILE=docker/compose-tracing-v2-ci-extension.yml DISABLE_JSON_RPC_PRICING_PROPAGATION=false
|
||||
|
||||
start-env-with-staterecovery: COMPOSE_PROFILES:=l1,l2,staterecovery
|
||||
start-env-with-staterecovery: L1_CONTRACT_VERSION:=6
|
||||
|
||||
@@ -63,7 +63,7 @@ services:
|
||||
file: compose-spec-l2-services.yml
|
||||
service: coordinator
|
||||
environment:
|
||||
config__override__l2-network-gas-pricing__json-rpc-pricing-propagation__disabled: true
|
||||
config__override__l2-network-gas-pricing__json-rpc-pricing-propagation__disabled: ${DISABLE_JSON_RPC_PRICING_PROPAGATION:-true}
|
||||
config__override__type2-state-proof-provider__endpoints: # leave empty to disable
|
||||
command: [ 'java', '-Dvertx.configurationFile=/var/lib/coordinator/vertx-options.json', '-Dlog4j2.configurationFile=/var/lib/coordinator/log4j2-dev.xml', '-jar', 'libs/coordinator.jar', '--traces-limits', 'config/traces-limits-v1.toml', '--smart-contract-errors', 'config/smart-contract-errors.toml', '--gas-price-cap-time-of-day-multipliers', 'config/gas-price-cap-time-of-day-multipliers.toml', 'config/coordinator-docker.config.toml', 'config/coordinator-docker-web3signer-override.config.toml' ]
|
||||
volumes:
|
||||
|
||||
@@ -64,7 +64,7 @@ services:
|
||||
file: compose-spec-l2-services.yml
|
||||
service: coordinator
|
||||
environment:
|
||||
config__override__l2-network-gas-pricing__json-rpc-pricing-propagation__disabled: true
|
||||
config__override__l2-network-gas-pricing__json-rpc-pricing-propagation__disabled: ${DISABLE_JSON_RPC_PRICING_PROPAGATION:-true}
|
||||
config__override__type2-state-proof-provider__endpoints: # leave empty to disable
|
||||
command: [ 'java', '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005','-Dvertx.configurationFile=/var/lib/coordinator/vertx-options.json', '-Dlog4j2.configurationFile=/var/lib/coordinator/log4j2-dev.xml', '-jar', 'libs/coordinator.jar', '--traces-limits-v2', 'config/traces-limits-v2.toml', '--smart-contract-errors', 'config/smart-contract-errors.toml', '--gas-price-cap-time-of-day-multipliers', 'config/gas-price-cap-time-of-day-multipliers.toml', 'config/coordinator-docker.config.toml', 'config/coordinator-docker-traces-v2-override.config.toml' ]
|
||||
volumes:
|
||||
|
||||
@@ -45,7 +45,14 @@ plugin-linea-tx-pool-profitability-check-p2p-enabled=false
|
||||
plugin-linea-tx-pool-profitability-check-api-enabled=false
|
||||
plugin-linea-tx-pool-simulation-check-api-enabled=true
|
||||
plugin-linea-tx-pool-simulation-check-p2p-enabled=false
|
||||
plugin-linea-extra-data-pricing-enabled=true
|
||||
plugin-linea-tx-pool-min-margin="0.8"
|
||||
plugin-linea-min-margin="1.0"
|
||||
plugin-linea-fixed-gas-cost-wei=30000000
|
||||
plugin-linea-variable-gas-cost-wei=1000000000
|
||||
plugin-linea-extra-data-set-min-gas-price-enabled=true
|
||||
plugin-linea-estimate-gas-compatibility-mode-enabled=false
|
||||
plugin-linea-estimate-gas-min-margin="1.2"
|
||||
|
||||
Xbonsai-limit-trie-logs-enabled=false
|
||||
bonsai-historical-block-limit=1024
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ethers } from "ethers";
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { config } from "./config/tests-config";
|
||||
import { waitForEvents, etherToWei } from "./common/utils";
|
||||
import { waitForEvents, etherToWei, LineaEstimateGasClient } from "./common/utils";
|
||||
import { MESSAGE_SENT_EVENT_SIGNATURE } from "./common/constants";
|
||||
|
||||
const l1AccountManager = config.getL1AccountManager();
|
||||
@@ -140,47 +140,73 @@ describe("Bridge ERC20 Tokens L1 -> L2 and L2 -> L1", () => {
|
||||
const l2TokenBridge = config.getL2TokenBridgeContract();
|
||||
const l2Token = config.getL2TokenContract();
|
||||
const l2Provider = config.getL2Provider();
|
||||
const lineaEstimateGasClient = new LineaEstimateGasClient(config.getL2BesuNodeEndpoint()!);
|
||||
const l2TokenAddress = await l2Token.getAddress();
|
||||
const l2TokenBridgeAddress = await l2TokenBridge.getAddress();
|
||||
|
||||
const { maxPriorityFeePerGas: l2MaxPriorityFeePerGas, maxFeePerGas: l2MaxFeePerGas } =
|
||||
await l2Provider.getFeeData();
|
||||
// Mint token
|
||||
let lineaEstimateGasFee = await lineaEstimateGasClient.lineaEstimateGas(
|
||||
l2Account.address,
|
||||
l2TokenAddress,
|
||||
l2Token.interface.encodeFunctionData("mint", [l2Account.address, bridgeAmount]),
|
||||
);
|
||||
let nonce = await l2Provider.getTransactionCount(l2Account.address, "pending");
|
||||
const mintResponse = await l2Token.connect(l2Account).mint(l2Account.address, bridgeAmount, {
|
||||
maxPriorityFeePerGas: lineaEstimateGasFee.maxPriorityFeePerGas,
|
||||
maxFeePerGas: lineaEstimateGasFee.maxFeePerGas,
|
||||
gasLimit: lineaEstimateGasFee.gasLimit,
|
||||
nonce: nonce,
|
||||
});
|
||||
const mintTxReceipt = await mintResponse.wait();
|
||||
logger.debug(`Mint tx receipt received=${JSON.stringify(mintTxReceipt)}`);
|
||||
|
||||
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(),
|
||||
]);
|
||||
// Approve token
|
||||
lineaEstimateGasFee = await lineaEstimateGasClient.lineaEstimateGas(
|
||||
l2Account.address,
|
||||
l2TokenAddress,
|
||||
l2Token.interface.encodeFunctionData("approve", [l2TokenBridgeAddress, ethers.parseEther("100")]),
|
||||
);
|
||||
nonce = await l2Provider.getTransactionCount(l2Account.address, "pending");
|
||||
const approveResponse = await l2Token.connect(l2Account).approve(l2TokenBridgeAddress, ethers.parseEther("100"), {
|
||||
maxPriorityFeePerGas: lineaEstimateGasFee.maxPriorityFeePerGas,
|
||||
maxFeePerGas: lineaEstimateGasFee.maxFeePerGas,
|
||||
gasLimit: lineaEstimateGasFee.gasLimit,
|
||||
nonce: nonce,
|
||||
});
|
||||
const approveTxReceipt = await approveResponse.wait();
|
||||
logger.debug(`Approve tx receipt received=${JSON.stringify(approveTxReceipt)}`);
|
||||
|
||||
const allowanceL2Account = await l2Token.allowance(l2Account.address, l2TokenBridge.getAddress());
|
||||
// Retrieve token allowance
|
||||
const allowanceL2Account = await l2Token.allowance(l2Account.address, l2TokenBridgeAddress);
|
||||
logger.debug(`Current allowance of L2 account to L2 TokenBridge is ${allowanceL2Account.toString()}`);
|
||||
logger.debug(`Current balance of L2 account is ${await l2Token.balanceOf(l2Account)}`);
|
||||
logger.debug(`Current balance of L2 account is ${await l2Token.balanceOf(l2Account)}`);
|
||||
|
||||
logger.debug("Calling the bridgeToken function on the L2 TokenBridge contract");
|
||||
|
||||
// Bridge token
|
||||
logger.debug(`0.01 ether = ${etherToWei("0.01").toString(16)}`);
|
||||
nonce = await l2Provider.getTransactionCount(l2Account.address, "pending");
|
||||
|
||||
const bridgeTokenTx = await l2TokenBridge
|
||||
lineaEstimateGasFee = await lineaEstimateGasClient.lineaEstimateGas(
|
||||
l2Account.address,
|
||||
l2TokenBridgeAddress,
|
||||
l2TokenBridge.interface.encodeFunctionData("bridgeToken", [l2TokenAddress, bridgeAmount, l1Account.address]),
|
||||
etherToWei("0.01").toString(16),
|
||||
);
|
||||
|
||||
const bridgeResponse = await l2TokenBridge
|
||||
.connect(l2Account)
|
||||
.bridgeToken(await l2Token.getAddress(), bridgeAmount, l1Account.address, {
|
||||
value: etherToWei("0.01"),
|
||||
maxPriorityFeePerGas: l2MaxPriorityFeePerGas,
|
||||
maxFeePerGas: l2MaxFeePerGas,
|
||||
maxPriorityFeePerGas: lineaEstimateGasFee.maxPriorityFeePerGas,
|
||||
maxFeePerGas: lineaEstimateGasFee.maxFeePerGas,
|
||||
gasLimit: lineaEstimateGasFee.gasLimit,
|
||||
nonce: nonce,
|
||||
});
|
||||
const bridgeTxReceipt = await bridgeResponse.wait();
|
||||
logger.debug(`Bridge tx receipt received=${JSON.stringify(bridgeTxReceipt)}`);
|
||||
|
||||
const receipt = await bridgeTokenTx.wait();
|
||||
const sentEventLog = receipt?.logs.find((log) => log.topics[0] == MESSAGE_SENT_EVENT_SIGNATURE);
|
||||
const sentEventLog = bridgeTxReceipt?.logs.find((log) => log.topics[0] == MESSAGE_SENT_EVENT_SIGNATURE);
|
||||
|
||||
const messageSentEvent = l2MessageService.interface.decodeEventLog(
|
||||
"MessageSent",
|
||||
|
||||
@@ -81,6 +81,46 @@ export class RollupGetZkEVMBlockNumberClient {
|
||||
}
|
||||
}
|
||||
|
||||
export class LineaEstimateGasClient {
|
||||
private endpoint: URL;
|
||||
|
||||
public constructor(endpoint: URL) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
public async lineaEstimateGas(
|
||||
from: string,
|
||||
to: string,
|
||||
data: string = "0x",
|
||||
value: string = "0x0",
|
||||
): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint; gasLimit: bigint }> {
|
||||
const request = {
|
||||
method: "post",
|
||||
body: JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
method: "linea_estimateGas",
|
||||
params: [
|
||||
{
|
||||
from,
|
||||
to,
|
||||
data,
|
||||
value,
|
||||
},
|
||||
],
|
||||
id: 1,
|
||||
}),
|
||||
};
|
||||
const response = await fetch(this.endpoint, request);
|
||||
const responseJson = await response.json();
|
||||
assert("result" in responseJson);
|
||||
return {
|
||||
maxFeePerGas: BigInt(responseJson.result.baseFeePerGas) + BigInt(responseJson.result.priorityFeePerGas),
|
||||
maxPriorityFeePerGas: BigInt(responseJson.result.priorityFeePerGas),
|
||||
gasLimit: BigInt(responseJson.result.gasLimit),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class TransactionExclusionClient {
|
||||
private endpoint: URL;
|
||||
|
||||
|
||||
@@ -76,6 +76,13 @@ export default class TestSetup {
|
||||
return this.config.L2.sequencerEndpoint;
|
||||
}
|
||||
|
||||
public getL2BesuNodeEndpoint(): URL | undefined {
|
||||
if (!this.isLocalL2Config(this.config.L2)) {
|
||||
return undefined;
|
||||
}
|
||||
return this.config.L2.besuNodeRpcUrl;
|
||||
}
|
||||
|
||||
public getTransactionExclusionEndpoint(): URL | undefined {
|
||||
if (!this.isLocalL2Config(this.config.L2)) {
|
||||
return undefined;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { ethers } from "ethers";
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { config } from "./config/tests-config";
|
||||
import { RollupGetZkEVMBlockNumberClient, etherToWei } from "./common/utils";
|
||||
import { LineaEstimateGasClient, RollupGetZkEVMBlockNumberClient, etherToWei } from "./common/utils";
|
||||
import { TRANSACTION_CALLDATA_LIMIT } from "./common/constants";
|
||||
|
||||
const l2AccountManager = config.getL2AccountManager();
|
||||
|
||||
describe("Layer 2 test suite", () => {
|
||||
const l2Provider = config.getL2Provider();
|
||||
const lineaEstimateGasClient = new LineaEstimateGasClient(config.getL2BesuNodeEndpoint()!);
|
||||
|
||||
it.concurrent("Should revert if transaction data size is above the limit", async () => {
|
||||
const account = await l2AccountManager.generateAccount();
|
||||
@@ -26,7 +27,11 @@ describe("Layer 2 test suite", () => {
|
||||
const nonce = await l2Provider.getTransactionCount(account.address, "pending");
|
||||
logger.debug(`Fetched nonce. nonce=${nonce} account=${account.address}`);
|
||||
|
||||
const { maxPriorityFeePerGas, maxFeePerGas } = await l2Provider.getFeeData();
|
||||
const { maxPriorityFeePerGas, maxFeePerGas } = await lineaEstimateGasClient.lineaEstimateGas(
|
||||
account.address,
|
||||
await dummyContract.getAddress(),
|
||||
dummyContract.interface.encodeFunctionData("setPayload", [ethers.randomBytes(1000)]),
|
||||
);
|
||||
logger.debug(`Fetched fee data. maxPriorityFeePerGas=${maxPriorityFeePerGas} maxFeePerGas=${maxFeePerGas}`);
|
||||
|
||||
const tx = await dummyContract.connect(account).setPayload(ethers.randomBytes(1000), {
|
||||
|
||||
@@ -2,7 +2,7 @@ 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 { encodeFunctionCall, etherToWei, LineaEstimateGasClient, waitForEvents } from "./common/utils";
|
||||
import { MESSAGE_SENT_EVENT_SIGNATURE } from "./common/constants";
|
||||
|
||||
async function sendL1ToL2Message(
|
||||
@@ -71,6 +71,7 @@ async function sendL2ToL1Message(
|
||||
const l2Provider = config.getL2Provider();
|
||||
const dummyContract = config.getL1DummyContract(l1Account);
|
||||
const l2MessageService = config.getL2MessageServiceContract(l2Account);
|
||||
const lineaEstimateGasClient = new LineaEstimateGasClient(config.getL2BesuNodeEndpoint()!);
|
||||
|
||||
const valueAndFee = etherToWei("0.001");
|
||||
const calldata = withCalldata
|
||||
@@ -81,7 +82,12 @@ async function sendL2ToL1Message(
|
||||
const nonce = await l2Provider.getTransactionCount(l2Account.address, "pending");
|
||||
logger.debug(`Fetched nonce. nonce=${nonce} account=${l2Account.address}`);
|
||||
|
||||
const { maxPriorityFeePerGas, maxFeePerGas } = await l2Provider.getFeeData();
|
||||
const { maxPriorityFeePerGas, maxFeePerGas, gasLimit } = await lineaEstimateGasClient.lineaEstimateGas(
|
||||
l2Account.address,
|
||||
await l2MessageService.getAddress(),
|
||||
l2MessageService.interface.encodeFunctionData("sendMessage", [destinationAddress, valueAndFee, calldata]),
|
||||
etherToWei("0.001").toString(16),
|
||||
);
|
||||
logger.debug(`Fetched fee data. maxPriorityFeePerGas=${maxPriorityFeePerGas} maxFeePerGas=${maxFeePerGas}`);
|
||||
|
||||
const tx = await l2MessageService.sendMessage(destinationAddress, valueAndFee, calldata, {
|
||||
@@ -89,6 +95,7 @@ async function sendL2ToL1Message(
|
||||
nonce,
|
||||
maxPriorityFeePerGas,
|
||||
maxFeePerGas,
|
||||
gasLimit,
|
||||
});
|
||||
|
||||
logger.debug(`sendMessage transaction sent. transactionHash=${tx.hash}`);
|
||||
|
||||
Reference in New Issue
Block a user