From 7ff641a276cb62419bb192ca36ebeaa421a91a5b Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Mon, 24 Jun 2024 15:13:01 +0200 Subject: [PATCH] Align linea_estimateGas behavior to geth Signed-off-by: Fabio Di Fabio --- PLUGINS.md | 3 +- .../consensys/linea/rpc/LineaEstimateGas.java | 34 +++++++++---------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/PLUGINS.md b/PLUGINS.md index e6e53c0d..bfda19c2 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -93,7 +93,8 @@ The validators are in the package `net.consensys.linea.sequencer.txpoolvalidatio ### Linea Estimate Gas #### `linea_estimateGas` -This endpoint simulates a transaction, including line count limit validation, and returns the estimated gas used ( as the standard `eth_estimateGas`) plus the estimated gas price to be used when submitting the tx. +This endpoint simulates a transaction, including line count limit validation, and returns the estimated gas used +(as the standard `eth_estimateGas` with `strict=true`) plus the estimated gas price to be used when submitting the tx. #### Parameters same as `eth_estimateGas` diff --git a/sequencer/src/main/java/net/consensys/linea/rpc/LineaEstimateGas.java b/sequencer/src/main/java/net/consensys/linea/rpc/LineaEstimateGas.java index 247598ad..7f12704f 100644 --- a/sequencer/src/main/java/net/consensys/linea/rpc/LineaEstimateGas.java +++ b/sequencer/src/main/java/net/consensys/linea/rpc/LineaEstimateGas.java @@ -137,15 +137,14 @@ public LineaEstimateGas.Response execute(final PluginRpcRequest request) { final var minGasPrice = besuConfiguration.getMinGasPrice(); final var transaction = - createTransactionForSimulation( - callParameters, txValidatorConf.maxTxGasLimit(), minGasPrice); + createTransactionForSimulation(callParameters, txValidatorConf.maxTxGasLimit()); log.atDebug() .setMessage("[{}] Parsed call parameters: {}; Transaction: {}") .addArgument(LOG_SEQUENCE::get) .addArgument(callParameters) .addArgument(transaction::toTraceLog) .log(); - final var estimatedGasUsed = estimateGasUsed(callParameters, transaction, minGasPrice); + final var estimatedGasUsed = estimateGasUsed(callParameters, transaction); final Wei baseFee = blockchainService @@ -205,9 +204,7 @@ private Wei getEstimatedPriorityFee( } private Long estimateGasUsed( - final JsonCallParameter callParameters, - final Transaction transaction, - final Wei minGasPrice) { + final JsonCallParameter callParameters, final Transaction transaction) { final var estimateGasTracer = new EstimateGasOperationTracer(); final var chainHeadHeader = blockchainService.getChainHeadHeader(); @@ -216,7 +213,7 @@ private Long estimateGasUsed( final var chainHeadHash = chainHeadHeader.getBlockHash(); final var maybeSimulationResults = - transactionSimulationService.simulate(transaction, chainHeadHash, zkAndGasTracer, true); + transactionSimulationService.simulate(transaction, chainHeadHash, zkAndGasTracer, false); ModuleLimitsValidationResult moduleLimit = moduleLineCountValidator.validate(zkTracer.getModulesLineCount()); @@ -262,7 +259,7 @@ private Long estimateGasUsed( final var lowGasEstimation = r.result().getEstimateGasUsedByTransaction(); final var lowResult = transactionSimulationService.simulate( - createTransactionForSimulation(callParameters, lowGasEstimation, minGasPrice), + createTransactionForSimulation(callParameters, lowGasEstimation), chainHeadHash, estimateGasTracer, true); @@ -297,8 +294,7 @@ private Long estimateGasUsed( final var binarySearchResult = transactionSimulationService.simulate( - createTransactionForSimulation( - callParameters, mid, minGasPrice), + createTransactionForSimulation(callParameters, mid), chainHeadHash, estimateGasTracer, true); @@ -361,10 +357,7 @@ private JsonCallParameter parseRequest(final Object[] params) { } private void validateParameters(final JsonCallParameter callParameters) { - if (callParameters.getGasPrice() != null - && (callParameters.getMaxFeePerGas().isPresent() - || callParameters.getMaxPriorityFeePerGas().isPresent() - || callParameters.getMaxFeePerBlobGas().isPresent())) { + if (callParameters.getGasPrice() != null && isBaseFeeMarket(callParameters)) { throw new InvalidJsonRpcParameters( "gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas or maxFeePerBlobGas"); } @@ -376,6 +369,12 @@ private void validateParameters(final JsonCallParameter callParameters) { } } + private boolean isBaseFeeMarket(final JsonCallParameter callParameters) { + return (callParameters.getMaxFeePerGas().isPresent() + || callParameters.getMaxPriorityFeePerGas().isPresent() + || callParameters.getMaxFeePerBlobGas().isPresent()); + } + /** * Estimate gas by adding minimum gas remaining for some operation and the necessary gas for sub * calls @@ -396,7 +395,7 @@ private long highGasEstimation( } private Transaction createTransactionForSimulation( - final JsonCallParameter callParameters, final long maxTxGasLimit, final Wei minGasPrice) { + final JsonCallParameter callParameters, final long maxTxGasLimit) { final var txBuilder = Transaction.builder() @@ -405,11 +404,12 @@ private Transaction createTransactionForSimulation( .gasLimit(maxTxGasLimit) .payload( callParameters.getPayload() == null ? Bytes.EMPTY : callParameters.getPayload()) - .gasPrice( - callParameters.getGasPrice() == null ? minGasPrice : callParameters.getGasPrice()) .value(callParameters.getValue() == null ? Wei.ZERO : callParameters.getValue()) .signature(FAKE_SIGNATURE_FOR_SIZE_CALCULATION); + if (!isBaseFeeMarket(callParameters) && callParameters.getGasPrice() == null) { + txBuilder.gasPrice(blockchainService.getNextBlockBaseFee().orElse(Wei.ZERO)); + } callParameters.getMaxFeePerGas().ifPresent(txBuilder::maxFeePerGas); callParameters.getMaxPriorityFeePerGas().ifPresent(txBuilder::maxPriorityFeePerGas); callParameters.getAccessList().ifPresent(txBuilder::accessList);