mirror of https://github.com/hyperledger/besu
[Refactor] Move api options to its own class (#6512)
Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>pull/6514/head
parent
8f2ee84bd7
commit
b68ee448c4
@ -0,0 +1,142 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.cli.options.stable; |
||||
|
||||
import static java.util.Arrays.asList; |
||||
|
||||
import org.hyperledger.besu.cli.util.CommandLineUtils; |
||||
import org.hyperledger.besu.ethereum.api.ApiConfiguration; |
||||
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration; |
||||
import org.hyperledger.besu.ethereum.core.MiningParameters; |
||||
|
||||
import org.slf4j.Logger; |
||||
import picocli.CommandLine; |
||||
|
||||
/** |
||||
* Handles configuration options for the API in Besu, including gas price settings, RPC log range, |
||||
* and trace filter range. |
||||
*/ |
||||
public class ApiConfigurationOptions { |
||||
|
||||
@CommandLine.Option( |
||||
names = {"--api-gas-price-blocks"}, |
||||
description = "Number of blocks to consider for eth_gasPrice (default: ${DEFAULT-VALUE})") |
||||
private final Long apiGasPriceBlocks = 100L; |
||||
|
||||
@CommandLine.Option( |
||||
names = {"--api-gas-price-percentile"}, |
||||
description = "Percentile value to measure for eth_gasPrice (default: ${DEFAULT-VALUE})") |
||||
private final Double apiGasPricePercentile = 50.0; |
||||
|
||||
@CommandLine.Option( |
||||
names = {"--api-gas-price-max"}, |
||||
description = "Maximum gas price for eth_gasPrice (default: ${DEFAULT-VALUE})") |
||||
private final Long apiGasPriceMax = 500_000_000_000L; |
||||
|
||||
@CommandLine.Option( |
||||
names = {"--api-gas-and-priority-fee-limiting-enabled"}, |
||||
hidden = true, |
||||
description = |
||||
"Set to enable gas price and minimum priority fee limit in eth_getGasPrice and eth_feeHistory (default: ${DEFAULT-VALUE})") |
||||
private final Boolean apiGasAndPriorityFeeLimitingEnabled = false; |
||||
|
||||
@CommandLine.Option( |
||||
names = {"--api-gas-and-priority-fee-lower-bound-coefficient"}, |
||||
hidden = true, |
||||
description = |
||||
"Coefficient for setting the lower limit of gas price and minimum priority fee in eth_getGasPrice and eth_feeHistory (default: ${DEFAULT-VALUE})") |
||||
private final Long apiGasAndPriorityFeeLowerBoundCoefficient = |
||||
ApiConfiguration.DEFAULT_LOWER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT; |
||||
|
||||
@CommandLine.Option( |
||||
names = {"--api-gas-and-priority-fee-upper-bound-coefficient"}, |
||||
hidden = true, |
||||
description = |
||||
"Coefficient for setting the upper limit of gas price and minimum priority fee in eth_getGasPrice and eth_feeHistory (default: ${DEFAULT-VALUE})") |
||||
private final Long apiGasAndPriorityFeeUpperBoundCoefficient = |
||||
ApiConfiguration.DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT; |
||||
|
||||
@CommandLine.Option( |
||||
names = {"--rpc-max-logs-range"}, |
||||
description = |
||||
"Specifies the maximum number of blocks to retrieve logs from via RPC. Must be >=0. 0 specifies no limit (default: ${DEFAULT-VALUE})") |
||||
private final Long rpcMaxLogsRange = 5000L; |
||||
|
||||
@CommandLine.Option( |
||||
names = {"--rpc-gas-cap"}, |
||||
description = |
||||
"Specifies the gasLimit cap for transaction simulation RPC methods. Must be >=0. 0 specifies no limit (default: ${DEFAULT-VALUE})") |
||||
private final Long rpcGasCap = 0L; |
||||
|
||||
@CommandLine.Option( |
||||
names = {"--rpc-max-trace-filter-range"}, |
||||
description = |
||||
"Specifies the maximum number of blocks for the trace_filter method. Must be >=0. 0 specifies no limit (default: $DEFAULT-VALUE)") |
||||
private final Long maxTraceFilterRange = 1000L; |
||||
|
||||
/** |
||||
* Validates the API options. |
||||
* |
||||
* @param commandLine CommandLine instance |
||||
* @param logger Logger instance |
||||
*/ |
||||
public void validate(final CommandLine commandLine, final Logger logger) { |
||||
if (apiGasAndPriorityFeeLimitingEnabled) { |
||||
if (apiGasAndPriorityFeeLowerBoundCoefficient > apiGasAndPriorityFeeUpperBoundCoefficient) { |
||||
throw new CommandLine.ParameterException( |
||||
commandLine, |
||||
"--api-gas-and-priority-fee-lower-bound-coefficient cannot be greater than the value of --api-gas-and-priority-fee-upper-bound-coefficient"); |
||||
} |
||||
} |
||||
checkApiOptionsDependencies(commandLine, logger); |
||||
} |
||||
|
||||
private void checkApiOptionsDependencies(final CommandLine commandLine, final Logger logger) { |
||||
CommandLineUtils.checkOptionDependencies( |
||||
logger, |
||||
commandLine, |
||||
"--api-gas-and-priority-fee-limiting-enabled", |
||||
!apiGasAndPriorityFeeLimitingEnabled, |
||||
asList( |
||||
"--api-gas-and-priority-fee-upper-bound-coefficient", |
||||
"--api-gas-and-priority-fee-lower-bound-coefficient")); |
||||
} |
||||
|
||||
/** |
||||
* Creates an ApiConfiguration based on the provided options. |
||||
* |
||||
* @param miningParameters The mining parameters |
||||
* @return An ApiConfiguration instance |
||||
*/ |
||||
public ApiConfiguration apiConfiguration(final MiningParameters miningParameters) { |
||||
var builder = |
||||
ImmutableApiConfiguration.builder() |
||||
.gasPriceBlocks(apiGasPriceBlocks) |
||||
.gasPricePercentile(apiGasPricePercentile) |
||||
.gasPriceMinSupplier( |
||||
miningParameters.getMinTransactionGasPrice().getAsBigInteger()::longValueExact) |
||||
.gasPriceMax(apiGasPriceMax) |
||||
.maxLogsRange(rpcMaxLogsRange) |
||||
.gasCap(rpcGasCap) |
||||
.isGasAndPriorityFeeLimitingEnabled(apiGasAndPriorityFeeLimitingEnabled) |
||||
.maxTraceFilterRange(maxTraceFilterRange); |
||||
if (apiGasAndPriorityFeeLimitingEnabled) { |
||||
builder |
||||
.lowerBoundGasAndPriorityFeeCoefficient(apiGasAndPriorityFeeLowerBoundCoefficient) |
||||
.upperBoundGasAndPriorityFeeCoefficient(apiGasAndPriorityFeeUpperBoundCoefficient); |
||||
} |
||||
return builder.build(); |
||||
} |
||||
} |
@ -0,0 +1,152 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.cli.options; |
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8; |
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.Mockito.verify; |
||||
|
||||
import org.hyperledger.besu.cli.CommandTestAbstract; |
||||
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.Mockito; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
|
||||
@ExtendWith(MockitoExtension.class) |
||||
public class ApiConfigurationOptionsTest extends CommandTestAbstract { |
||||
|
||||
@Test |
||||
public void apiPriorityFeeLimitingEnabledOptionMustBeUsed() { |
||||
parseCommand("--api-gas-and-priority-fee-limiting-enabled"); |
||||
verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture()); |
||||
verify(mockRunnerBuilder).build(); |
||||
assertThat(apiConfigurationCaptor.getValue()) |
||||
.isEqualTo( |
||||
ImmutableApiConfiguration.builder().isGasAndPriorityFeeLimitingEnabled(true).build()); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void apiPriorityFeeLowerBoundCoefficientOptionMustBeUsed() { |
||||
final long lowerBound = 150L; |
||||
parseCommand( |
||||
"--api-gas-and-priority-fee-lower-bound-coefficient", |
||||
Long.toString(lowerBound), |
||||
"--api-gas-and-priority-fee-limiting-enabled"); |
||||
verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture()); |
||||
verify(mockRunnerBuilder).build(); |
||||
assertThat(apiConfigurationCaptor.getValue()) |
||||
.isEqualTo( |
||||
ImmutableApiConfiguration.builder() |
||||
.lowerBoundGasAndPriorityFeeCoefficient(lowerBound) |
||||
.isGasAndPriorityFeeLimitingEnabled(true) |
||||
.build()); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void |
||||
apiPriorityFeeLowerBoundCoefficients_MustNotBeGreaterThan_apiPriorityFeeUpperBoundCoefficient() { |
||||
final long lowerBound = 200L; |
||||
final long upperBound = 100L; |
||||
|
||||
parseCommand( |
||||
"--api-gas-and-priority-fee-limiting-enabled", |
||||
"--api-gas-and-priority-fee-lower-bound-coefficient", |
||||
Long.toString(lowerBound), |
||||
"--api-gas-and-priority-fee-upper-bound-coefficient", |
||||
Long.toString(upperBound)); |
||||
Mockito.verifyNoInteractions(mockRunnerBuilder); |
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)) |
||||
.contains( |
||||
"--api-gas-and-priority-fee-lower-bound-coefficient cannot be greater than the value of --api-gas-and-priority-fee-upper-bound-coefficient"); |
||||
} |
||||
|
||||
@Test |
||||
public void apiPriorityFeeUpperBoundCoefficientsOptionMustBeUsed() { |
||||
final long upperBound = 200L; |
||||
parseCommand( |
||||
"--api-gas-and-priority-fee-upper-bound-coefficient", |
||||
Long.toString(upperBound), |
||||
"--api-gas-and-priority-fee-limiting-enabled"); |
||||
verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture()); |
||||
verify(mockRunnerBuilder).build(); |
||||
assertThat(apiConfigurationCaptor.getValue()) |
||||
.isEqualTo( |
||||
ImmutableApiConfiguration.builder() |
||||
.upperBoundGasAndPriorityFeeCoefficient(upperBound) |
||||
.isGasAndPriorityFeeLimitingEnabled(true) |
||||
.build()); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void rpcMaxLogsRangeOptionMustBeUsed() { |
||||
|
||||
final long rpcMaxLogsRange = 150L; |
||||
parseCommand("--rpc-max-logs-range", Long.toString(rpcMaxLogsRange)); |
||||
|
||||
verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture()); |
||||
verify(mockRunnerBuilder).build(); |
||||
|
||||
assertThat(apiConfigurationCaptor.getValue()) |
||||
.isEqualTo(ImmutableApiConfiguration.builder().maxLogsRange((rpcMaxLogsRange)).build()); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void rpcGasCapOptionMustBeUsed() { |
||||
final long rpcGasCap = 150L; |
||||
parseCommand("--rpc-gas-cap", Long.toString(rpcGasCap)); |
||||
|
||||
verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture()); |
||||
verify(mockRunnerBuilder).build(); |
||||
|
||||
assertThat(apiConfigurationCaptor.getValue()) |
||||
.isEqualTo(ImmutableApiConfiguration.builder().gasCap((rpcGasCap)).build()); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void rpcMaxTraceFilterOptionMustBeUsed() { |
||||
final long rpcMaxTraceFilterOption = 150L; |
||||
parseCommand("--rpc-max-trace-filter-range", Long.toString(rpcMaxTraceFilterOption)); |
||||
|
||||
verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture()); |
||||
verify(mockRunnerBuilder).build(); |
||||
|
||||
assertThat(apiConfigurationCaptor.getValue()) |
||||
.isEqualTo( |
||||
ImmutableApiConfiguration.builder() |
||||
.maxTraceFilterRange((rpcMaxTraceFilterOption)) |
||||
.build()); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
} |
Loading…
Reference in new issue