Ignore gasPrice if 1559 gas params are specified (#8059)

* don't throw if all the gasprice params are specified

Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>

---------

Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
This commit is contained in:
Sally MacFarlane
2024-12-20 15:47:06 +10:00
committed by GitHub
parent ea8579d63a
commit c72d02ea38
7 changed files with 50 additions and 25 deletions

View File

@@ -18,6 +18,7 @@
- Add RPC HTTP options to specify custom truststore and its password [#7978](https://github.com/hyperledger/besu/pull/7978)
- Retrieve all transaction receipts for a block in one request [#6646](https://github.com/hyperledger/besu/pull/6646)
- Implement EIP-7840: Add blob schedule to config files [#8042](https://github.com/hyperledger/besu/pull/8042)
- Allow gasPrice (legacy) and 1559 gasPrice params to be specified simultaneously for `eth_call`, `eth_createAccessList`, and `eth_estimateGas` [#8059](https://github.com/hyperledger/besu/pull/8059)
### Bug fixes

View File

@@ -24,6 +24,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcUnauth
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.privacy.MultiTenancyValidationException;
import java.util.Arrays;
import io.opentelemetry.api.trace.Span;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
@@ -44,7 +46,8 @@ public class BaseJsonRpcProcessor implements JsonRpcProcessor {
return method.response(request);
} catch (final InvalidJsonRpcParameters e) {
LOG.debug(
"Invalid Params for method: {}, error: {}",
"Invalid Params {} for method: {}, error: {}",
Arrays.toString(request.getRequest().getParams()),
method.getName(),
e.getRpcErrorType().getMessage(),
e);

View File

@@ -82,7 +82,6 @@ public class TracedJsonRpcProcessor implements JsonRpcProcessor {
case INVALID_EXECUTION_REQUESTS_PARAMS:
case INVALID_EXTRA_DATA_PARAMS:
case INVALID_FILTER_PARAMS:
case INVALID_GAS_PRICE_PARAMS:
case INVALID_HASH_RATE_PARAMS:
case INVALID_ID_PARAMS:
case INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS:

View File

@@ -20,7 +20,13 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallPar
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JsonCallParameterUtil {
private static final Logger LOG = LoggerFactory.getLogger(JsonCallParameterUtil.class);
private JsonCallParameterUtil() {}
@@ -36,9 +42,14 @@ public class JsonCallParameterUtil {
if (callParams.getGasPrice() != null
&& (callParams.getMaxFeePerGas().isPresent()
|| callParams.getMaxPriorityFeePerGas().isPresent())) {
throw new InvalidJsonRpcParameters(
"gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas",
RpcErrorType.INVALID_GAS_PRICE_PARAMS);
try {
LOG.debug(
"gasPrice will be ignored since 1559 values are defined (maxFeePerGas or maxPriorityFeePerGas). {}",
Arrays.toString(request.getRequest().getParams()));
} catch (Exception e) {
LOG.debug(
"gasPrice will be ignored since 1559 values are defined (maxFeePerGas or maxPriorityFeePerGas)");
}
}
return callParams;
}

View File

@@ -65,7 +65,6 @@ public enum RpcErrorType implements RpcMethodError {
INVALID_EXECUTION_REQUESTS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid execution requests params"),
INVALID_EXTRA_DATA_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid extra data params"),
INVALID_FILTER_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid filter params"),
INVALID_GAS_PRICE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid gas price params"),
INVALID_HASH_RATE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid hash rate params"),
INVALID_ID_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid ID params"),
INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS(

View File

@@ -27,7 +27,6 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
@@ -51,7 +50,6 @@ import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -156,14 +154,16 @@ public class EthCreateAccessListTest {
}
@Test
public void shouldReturnGasEstimateErrorWhenGasPricePresentForEip1559Transaction() {
public void shouldNotErrorWhenGasPricePresentForEip1559Transaction() {
final Wei gasPrice = Wei.of(1000);
final List<AccessListEntry> expectedAccessList = new ArrayList<>();
final JsonRpcRequestContext request =
ethCreateAccessListRequest(eip1559TransactionCallParameter(Optional.of(Wei.of(10))));
mockTransactionSimulatorResult(false, false, 1L, latestBlockHeader);
ethCreateAccessListRequest(eip1559TransactionCallParameter(Optional.of(gasPrice)));
mockTransactionSimulatorResult(true, false, 1L, latestBlockHeader);
Assertions.assertThatThrownBy(() -> method.response(request))
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasMessageContaining("gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas");
final JsonRpcResponse expectedResponse =
new JsonRpcSuccessResponse(null, new CreateAccessListResult(expectedAccessList, 1L));
assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse);
}
@Test

View File

@@ -28,7 +28,6 @@ import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.datatypes.parameters.UnsignedLongParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
@@ -52,7 +51,6 @@ import org.hyperledger.besu.evm.tracing.OperationTracer;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -196,13 +194,15 @@ public class EthEstimateGasTest {
}
@Test
public void shouldReturnGasEstimateErrorWhenGasPricePresentForEip1559Transaction() {
public void shouldNotErrorWhenGasPricePresentForEip1559Transaction() {
final Wei gasPrice = Wei.of(1000);
final JsonRpcRequestContext request =
ethEstimateGasRequest(eip1559TransactionCallParameter(Optional.of(Wei.of(10))));
mockTransientProcessorResultGasEstimate(1L, false, false, latestBlockHeader);
Assertions.assertThatThrownBy(() -> method.response(request))
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasMessageContaining("gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas");
ethEstimateGasRequest(eip1559TransactionCallParameter(Optional.of(gasPrice)));
mockTransientProcessorResultGasEstimate(
1L, true, gasPrice, Optional.empty(), latestBlockHeader);
final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Quantity.create(1L));
assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse);
}
@Test
@@ -534,6 +534,14 @@ public class EthEstimateGasTest {
any(OperationTracer.class),
eq(blockHeader)))
.thenReturn(Optional.of(mockTxSimResult));
// for testing different combination of gasPrice params
when(transactionSimulator.process(
eq(modifiedEip1559TransactionCallParameter(Optional.of(gasPrice))),
eq(Optional.empty()), // no account overrides
any(TransactionValidationParams.class),
any(OperationTracer.class),
eq(blockHeader)))
.thenReturn(Optional.of(mockTxSimResult));
}
final TransactionProcessingResult mockResult = mock(TransactionProcessingResult.class);
when(mockResult.getEstimateGasUsedByTransaction()).thenReturn(estimateGas);
@@ -578,11 +586,11 @@ public class EthEstimateGasTest {
return eip1559TransactionCallParameter(Optional.empty());
}
private JsonCallParameter eip1559TransactionCallParameter(final Optional<Wei> gasPrice) {
private JsonCallParameter eip1559TransactionCallParameter(final Optional<Wei> maybeGasPrice) {
return new JsonCallParameter.JsonCallParameterBuilder()
.withFrom(Address.fromHexString("0x0"))
.withTo(Address.fromHexString("0x0"))
.withGasPrice(gasPrice.orElse(null))
.withGasPrice(maybeGasPrice.orElse(null))
.withMaxPriorityFeePerGas(Wei.fromHexString("0x10"))
.withMaxFeePerGas(Wei.fromHexString("0x10"))
.withValue(Wei.ZERO)
@@ -592,11 +600,15 @@ public class EthEstimateGasTest {
}
private CallParameter modifiedEip1559TransactionCallParameter() {
return modifiedEip1559TransactionCallParameter(Optional.empty());
}
private CallParameter modifiedEip1559TransactionCallParameter(final Optional<Wei> gasPrice) {
return new CallParameter(
Address.fromHexString("0x0"),
Address.fromHexString("0x0"),
Long.MAX_VALUE,
Wei.ZERO,
gasPrice.orElse(Wei.ZERO),
Optional.of(Wei.fromHexString("0x10")),
Optional.of(Wei.fromHexString("0x10")),
Wei.ZERO,