Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linea_estimateGas compatibility mode multiplier #646

Merged
merged 1 commit into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,52 @@

import static org.assertj.core.api.Assertions.assertThat;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;

public class EstimateGasCompatibilityModeTest extends EstimateGasTest {
private static final BigDecimal PRICE_MULTIPLIER = BigDecimal.valueOf(1.2);

@Override
public List<String> getTestCliOptions() {
return getTestCommandLineOptionsBuilder()
.set("--plugin-linea-estimate-gas-compatibility-mode-enabled=", "true")
.set(
"--plugin-linea-estimate-gas-compatibility-mode-multiplier=",
PRICE_MULTIPLIER.toPlainString())
.build();
}

@Override
protected void assertIsProfitable(
final Transaction tx,
final Wei baseFee,
final Wei estimatedPriorityFee,
final Wei estimatedMaxGasPrice,
final long estimatedGasLimit) {
final var minGasPrice = minerNode.getMiningParameters().getMinTransactionGasPrice();
final var minPriorityFee = minGasPrice.subtract(baseFee);
final var compatibilityMinPriorityFee =
Wei.of(
PRICE_MULTIPLIER
.multiply(new BigDecimal(minPriorityFee.getAsBigInteger()))
.setScale(0, RoundingMode.CEILING)
.toBigInteger());

// since we are in compatibility mode, we want to check that returned profitable priority fee is
// the min mineable gas price
assertThat(estimatedMaxGasPrice).isEqualTo(minGasPrice);
// the min priority fee per gas * multiplier + base fee
final var expectedMaxGasPrice = baseFee.add(compatibilityMinPriorityFee);
assertThat(estimatedMaxGasPrice).isEqualTo(expectedMaxGasPrice);
}

@Override
protected void assertMinGasPriceLowerBound(final Wei baseFee, final Wei estimatedMaxGasPrice) {
// since we are in compatibility mode, we want to check that returned profitable priority fee is
// the min priority fee per gas * multiplier + base fee
assertIsProfitable(null, baseFee, null, estimatedMaxGasPrice, 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import net.consensys.linea.bl.TransactionProfitabilityCalculator;
import net.consensys.linea.config.LineaProfitabilityCliOptions;
import net.consensys.linea.config.LineaProfitabilityConfiguration;
import net.consensys.linea.config.LineaTransactionSelectorConfiguration;
import net.consensys.linea.rpc.linea.LineaEstimateGas;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt64;
Expand All @@ -48,7 +47,6 @@ public class EstimateGasTest extends LineaPluginTestBase {
protected static final double ESTIMATE_GAS_MIN_MARGIN = 1.0;
protected static final Wei MIN_GAS_PRICE = Wei.of(1_000_000_000);
protected static final int MAX_TRANSACTION_GAS_LIMIT = 30_000_000;
protected LineaTransactionSelectorConfiguration txSelectorConf;
protected LineaProfitabilityConfiguration profitabilityConf;

@Override
Expand Down Expand Up @@ -137,11 +135,12 @@ public void lineaEstimateGasIsProfitable() {
.signature(LineaEstimateGas.FAKE_SIGNATURE_FOR_SIZE_CALCULATION)
.build();

assertIsProfitable(tx, estimatedPriorityFee, estimatedMaxGasPrice, estimatedGasLimit);
assertIsProfitable(tx, baseFee, estimatedPriorityFee, estimatedMaxGasPrice, estimatedGasLimit);
}

protected void assertIsProfitable(
final org.hyperledger.besu.ethereum.core.Transaction tx,
final Wei baseFee,
final Wei estimatedPriorityFee,
final Wei estimatedMaxGasPrice,
final long estimatedGasLimit) {
Expand Down Expand Up @@ -180,8 +179,12 @@ public void lineaEstimateGasPriorityFeeMinGasPriceLowerBound() {
final var baseFee = Wei.fromHexString(respLinea.baseFeePerGas());
final var estimatedPriorityFee = Wei.fromHexString(respLinea.priorityFeePerGas());
final var estimatedMaxGasPrice = baseFee.add(estimatedPriorityFee);
final var minGasPrice = minerNode.getMiningParameters().getMinTransactionGasPrice();

assertMinGasPriceLowerBound(baseFee, estimatedMaxGasPrice);
}

protected void assertMinGasPriceLowerBound(final Wei baseFee, final Wei estimatedMaxGasPrice) {
final var minGasPrice = minerNode.getMiningParameters().getMinTransactionGasPrice();
assertThat(estimatedMaxGasPrice).isEqualTo(minGasPrice);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,36 @@

package net.consensys.linea.config;

import java.math.BigDecimal;

import com.google.common.base.MoreObjects;
import picocli.CommandLine;

/** The Linea RPC CLI options. */
public class LineaRpcCliOptions {
private static final String ESTIMATE_GAS_COMPATIBILITY_MODE_ENABLED =
"--plugin-linea-estimate-gas-compatibility-mode-enabled";
private static final boolean DEFAULT_ESTIMATE_GAS_COMPATIBILITY_MODE_ENABLED = false;
private static final String ESTIMATE_GAS_COMPATIBILITY_MODE_MULTIPLIER =
"--plugin-linea-estimate-gas-compatibility-mode-multiplier";
private static final BigDecimal DEFAULT_ESTIMATE_GAS_COMPATIBILITY_MODE_MULTIPLIER =
BigDecimal.valueOf(1.2);

@CommandLine.Option(
names = {ESTIMATE_GAS_COMPATIBILITY_MODE_ENABLED},
paramLabel = "<BOOLEAN>",
description =
"Set to true to return the min mineable gas price, instead of the profitable price (default: ${DEFAULT-VALUE})")
private boolean estimateGasCompatibilityModeEnabled = false;
"Set to true to return the min mineable gas price * multiplier, instead of the profitable price (default: ${DEFAULT-VALUE})")
private boolean estimateGasCompatibilityModeEnabled =
DEFAULT_ESTIMATE_GAS_COMPATIBILITY_MODE_ENABLED;

@CommandLine.Option(
names = {ESTIMATE_GAS_COMPATIBILITY_MODE_MULTIPLIER},
paramLabel = "<FLOAT>",
description =
"Set to multiplier to apply to the min priority fee per gas when the compatibility mode is enabled (default: ${DEFAULT-VALUE})")
private BigDecimal estimateGasCompatibilityMultiplier =
DEFAULT_ESTIMATE_GAS_COMPATIBILITY_MODE_MULTIPLIER;

private LineaRpcCliOptions() {}

Expand All @@ -50,6 +66,7 @@ public static LineaRpcCliOptions create() {
public static LineaRpcCliOptions fromConfig(final LineaRpcConfiguration config) {
final LineaRpcCliOptions options = create();
options.estimateGasCompatibilityModeEnabled = config.estimateGasCompatibilityModeEnabled();
options.estimateGasCompatibilityMultiplier = config.estimateGasCompatibilityMultiplier();
return options;
}

Expand All @@ -61,13 +78,15 @@ public static LineaRpcCliOptions fromConfig(final LineaRpcConfiguration config)
public LineaRpcConfiguration toDomainObject() {
return LineaRpcConfiguration.builder()
.estimateGasCompatibilityModeEnabled(estimateGasCompatibilityModeEnabled)
.estimateGasCompatibilityMultiplier(estimateGasCompatibilityMultiplier)
.build();
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add(ESTIMATE_GAS_COMPATIBILITY_MODE_ENABLED, estimateGasCompatibilityModeEnabled)
.add(ESTIMATE_GAS_COMPATIBILITY_MODE_MULTIPLIER, estimateGasCompatibilityMultiplier)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@

package net.consensys.linea.config;

import java.math.BigDecimal;

import lombok.Builder;

/** The Linea RPC configuration. */
@Builder(toBuilder = true)
public record LineaRpcConfiguration(boolean estimateGasCompatibilityModeEnabled) {}
public record LineaRpcConfiguration(
boolean estimateGasCompatibilityModeEnabled, BigDecimal estimateGasCompatibilityMultiplier) {}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity.create;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.annotations.VisibleForTesting;
Expand Down Expand Up @@ -112,17 +114,13 @@ public LineaEstimateGas.Response execute(final PluginRpcRequest request) {
.log();
final var estimatedGasUsed = estimateGasUsed(callParameters, transaction, minGasPrice);

final Wei profitablePriorityFee =
txProfitabilityCalculator.profitablePriorityFeePerGas(
transaction, profitabilityConf.estimateGasMinMargin(), minGasPrice, estimatedGasUsed);

final Wei baseFee =
blockchainService
.getNextBlockBaseFee()
.orElseThrow(() -> new IllegalStateException("Not on a baseFee market"));

final Wei estimatedPriorityFee =
getEstimatedPriorityFee(baseFee, profitablePriorityFee, minGasPrice);
getEstimatedPriorityFee(transaction, baseFee, minGasPrice, estimatedGasUsed);

final var response =
new Response(create(estimatedGasUsed), create(baseFee), create(estimatedPriorityFee));
Expand All @@ -132,13 +130,25 @@ public LineaEstimateGas.Response execute(final PluginRpcRequest request) {
}

private Wei getEstimatedPriorityFee(
final Wei baseFee, final Wei profitablePriorityFee, final Wei minGasPrice) {
final Transaction transaction,
final Wei baseFee,
final Wei minGasPrice,
final long estimatedGasUsed) {
final Wei priorityFeeLowerBound = minGasPrice.subtract(baseFee);

if (rpcConfiguration.estimateGasCompatibilityModeEnabled()) {
return priorityFeeLowerBound;
return Wei.of(
rpcConfiguration
.estimateGasCompatibilityMultiplier()
.multiply(new BigDecimal(priorityFeeLowerBound.getAsBigInteger()))
.setScale(0, RoundingMode.CEILING)
.toBigInteger());
}

final Wei profitablePriorityFee =
txProfitabilityCalculator.profitablePriorityFeePerGas(
transaction, profitabilityConf.estimateGasMinMargin(), minGasPrice, estimatedGasUsed);

if (profitablePriorityFee.greaterOrEqualThan(priorityFeeLowerBound)) {
return profitablePriorityFee;
}
Expand Down
2 changes: 1 addition & 1 deletion gradle/dependency-management.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ dependencyManagement {

dependency 'com.splunk.logging:splunk-library-javalogging:1.11.5'

dependency 'io.vertx:vertx-core:4.3.8'
dependency 'io.vertx:vertx-core:4.5.4'

dependency 'com.slack.api:slack-api-client:1.32.1'

Expand Down
Loading