Skip to content

Commit 6c4f2de

Browse files
Gabriel-Trintinaliajflo
authored andcommitted
[RPC] Use apiConfiguration to limit gasPrice in eth_getGasPrice (besu-eth#6243)
Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net> Signed-off-by: jflo <justin+github@florentine.us>
1 parent 4026637 commit 6c4f2de

File tree

8 files changed

+196
-80
lines changed

8 files changed

+196
-80
lines changed

besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,27 +1218,27 @@ static class PermissionsOptionGroup {
12181218
private final Long apiGasPriceMax = 500_000_000_000L;
12191219

12201220
@CommandLine.Option(
1221-
names = {"--api-priority-fee-limiting-enabled"},
1221+
names = {"--api-gas-and-priority-fee-limiting-enabled"},
12221222
hidden = true,
12231223
description =
1224-
"Set to enable priority fee limit in eth_feeHistory (default: ${DEFAULT-VALUE})")
1225-
private final Boolean apiPriorityFeeLimitingEnabled = false;
1224+
"Set to enable gas price and minimum priority fee limit in eth_getGasPrice and eth_feeHistory (default: ${DEFAULT-VALUE})")
1225+
private final Boolean apiGasAndPriorityFeeLimitingEnabled = false;
12261226

12271227
@CommandLine.Option(
1228-
names = {"--api-priority-fee-lower-bound-coefficient"},
1228+
names = {"--api-gas-and-priority-fee-lower-bound-coefficient"},
12291229
hidden = true,
12301230
description =
1231-
"Coefficient for setting the lower limit of minimum priority fee in eth_feeHistory (default: ${DEFAULT-VALUE})")
1232-
private final Long apiPriorityFeeLowerBoundCoefficient =
1233-
ApiConfiguration.DEFAULT_LOWER_BOUND_PRIORITY_FEE_COEFFICIENT;
1231+
"Coefficient for setting the lower limit of gas price and minimum priority fee in eth_getGasPrice and eth_feeHistory (default: ${DEFAULT-VALUE})")
1232+
private final Long apiGasAndPriorityFeeLowerBoundCoefficient =
1233+
ApiConfiguration.DEFAULT_LOWER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT;
12341234

12351235
@CommandLine.Option(
1236-
names = {"--api-priority-fee-upper-bound-coefficient"},
1236+
names = {"--api-gas-and-priority-fee-upper-bound-coefficient"},
12371237
hidden = true,
12381238
description =
1239-
"Coefficient for setting the upper limit of minimum priority fee in eth_feeHistory (default: ${DEFAULT-VALUE})")
1240-
private final Long apiPriorityFeeUpperBoundCoefficient =
1241-
ApiConfiguration.DEFAULT_UPPER_BOUND_PRIORITY_FEE_COEFFICIENT;
1239+
"Coefficient for setting the upper limit of gas price and minimum priority fee in eth_getGasPrice and eth_feeHistory (default: ${DEFAULT-VALUE})")
1240+
private final Long apiGasAndPriorityFeeUpperBoundCoefficient =
1241+
ApiConfiguration.DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT;
12421242

12431243
@CommandLine.Option(
12441244
names = {"--static-nodes-file"},
@@ -1902,11 +1902,11 @@ private void checkApiOptionsDependencies() {
19021902
CommandLineUtils.checkOptionDependencies(
19031903
logger,
19041904
commandLine,
1905-
"--api-priority-fee-limiting-enabled",
1906-
!apiPriorityFeeLimitingEnabled,
1905+
"--api-gas-and-priority-fee-limiting-enabled",
1906+
!apiGasAndPriorityFeeLimitingEnabled,
19071907
asList(
1908-
"--api-priority-fee-upper-bound-coefficient",
1909-
"--api-priority-fee-lower-bound-coefficient"));
1908+
"--api-gas-and-priority-fee-upper-bound-coefficient",
1909+
"--api-gas-and-priority-fee-lower-bound-coefficient"));
19101910
}
19111911

19121912
private void ensureValidPeerBoundParams() {
@@ -2534,16 +2534,16 @@ private ApiConfiguration apiConfiguration() {
25342534
.gasPriceMax(apiGasPriceMax)
25352535
.maxLogsRange(rpcMaxLogsRange)
25362536
.gasCap(rpcGasCap)
2537-
.isPriorityFeeLimitingEnabled(apiPriorityFeeLimitingEnabled);
2538-
if (apiPriorityFeeLimitingEnabled) {
2539-
if (apiPriorityFeeLowerBoundCoefficient > apiPriorityFeeUpperBoundCoefficient) {
2537+
.isGasAndPriorityFeeLimitingEnabled(apiGasAndPriorityFeeLimitingEnabled);
2538+
if (apiGasAndPriorityFeeLimitingEnabled) {
2539+
if (apiGasAndPriorityFeeLowerBoundCoefficient > apiGasAndPriorityFeeUpperBoundCoefficient) {
25402540
throw new ParameterException(
25412541
this.commandLine,
2542-
"--api-priority-fee-lower-bound-coefficient cannot be greater than the value of --api-priority-fee-upper-bound-coefficient");
2542+
"--api-gas-and-priority-fee-lower-bound-coefficient cannot be greater than the value of --api-gas-and-priority-fee-upper-bound-coefficient");
25432543
}
25442544
builder
2545-
.lowerBoundPriorityFeeCoefficient(apiPriorityFeeLowerBoundCoefficient)
2546-
.upperBoundPriorityFeeCoefficient(apiPriorityFeeUpperBoundCoefficient);
2545+
.lowerBoundGasAndPriorityFeeCoefficient(apiGasAndPriorityFeeLowerBoundCoefficient)
2546+
.upperBoundGasAndPriorityFeeCoefficient(apiGasAndPriorityFeeUpperBoundCoefficient);
25472547
}
25482548
return builder.build();
25492549
}

besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,11 +1611,12 @@ public void rpcGasCapOptionMustBeUsed() {
16111611

16121612
@Test
16131613
public void apiPriorityFeeLimitingEnabledOptionMustBeUsed() {
1614-
parseCommand("--api-priority-fee-limiting-enabled");
1614+
parseCommand("--api-gas-and-priority-fee-limiting-enabled");
16151615
verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture());
16161616
verify(mockRunnerBuilder).build();
16171617
assertThat(apiConfigurationCaptor.getValue())
1618-
.isEqualTo(ImmutableApiConfiguration.builder().isPriorityFeeLimitingEnabled(true).build());
1618+
.isEqualTo(
1619+
ImmutableApiConfiguration.builder().isGasAndPriorityFeeLimitingEnabled(true).build());
16191620

16201621
assertThat(commandOutput.toString(UTF_8)).isEmpty();
16211622
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
@@ -1625,16 +1626,16 @@ public void apiPriorityFeeLimitingEnabledOptionMustBeUsed() {
16251626
public void apiPriorityFeeLowerBoundCoefficientOptionMustBeUsed() {
16261627
final long lowerBound = 150L;
16271628
parseCommand(
1628-
"--api-priority-fee-lower-bound-coefficient",
1629+
"--api-gas-and-priority-fee-lower-bound-coefficient",
16291630
Long.toString(lowerBound),
1630-
"--api-priority-fee-limiting-enabled");
1631+
"--api-gas-and-priority-fee-limiting-enabled");
16311632
verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture());
16321633
verify(mockRunnerBuilder).build();
16331634
assertThat(apiConfigurationCaptor.getValue())
16341635
.isEqualTo(
16351636
ImmutableApiConfiguration.builder()
1636-
.lowerBoundPriorityFeeCoefficient(lowerBound)
1637-
.isPriorityFeeLimitingEnabled(true)
1637+
.lowerBoundGasAndPriorityFeeCoefficient(lowerBound)
1638+
.isGasAndPriorityFeeLimitingEnabled(true)
16381639
.build());
16391640

16401641
assertThat(commandOutput.toString(UTF_8)).isEmpty();
@@ -1648,32 +1649,32 @@ public void apiPriorityFeeLowerBoundCoefficientOptionMustBeUsed() {
16481649
final long upperBound = 100L;
16491650

16501651
parseCommand(
1651-
"--api-priority-fee-limiting-enabled",
1652-
"--api-priority-fee-lower-bound-coefficient",
1652+
"--api-gas-and-priority-fee-limiting-enabled",
1653+
"--api-gas-and-priority-fee-lower-bound-coefficient",
16531654
Long.toString(lowerBound),
1654-
"--api-priority-fee-upper-bound-coefficient",
1655+
"--api-gas-and-priority-fee-upper-bound-coefficient",
16551656
Long.toString(upperBound));
16561657
Mockito.verifyNoInteractions(mockRunnerBuilder);
16571658
assertThat(commandOutput.toString(UTF_8)).isEmpty();
16581659
assertThat(commandErrorOutput.toString(UTF_8))
16591660
.contains(
1660-
"--api-priority-fee-lower-bound-coefficient cannot be greater than the value of --api-priority-fee-upper-bound-coefficient");
1661+
"--api-gas-and-priority-fee-lower-bound-coefficient cannot be greater than the value of --api-gas-and-priority-fee-upper-bound-coefficient");
16611662
}
16621663

16631664
@Test
16641665
public void apiPriorityFeeUpperBoundCoefficientsOptionMustBeUsed() {
16651666
final long upperBound = 200L;
16661667
parseCommand(
1667-
"--api-priority-fee-upper-bound-coefficient",
1668+
"--api-gas-and-priority-fee-upper-bound-coefficient",
16681669
Long.toString(upperBound),
1669-
"--api-priority-fee-limiting-enabled");
1670+
"--api-gas-and-priority-fee-limiting-enabled");
16701671
verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture());
16711672
verify(mockRunnerBuilder).build();
16721673
assertThat(apiConfigurationCaptor.getValue())
16731674
.isEqualTo(
16741675
ImmutableApiConfiguration.builder()
1675-
.upperBoundPriorityFeeCoefficient(upperBound)
1676-
.isPriorityFeeLimitingEnabled(true)
1676+
.upperBoundGasAndPriorityFeeCoefficient(upperBound)
1677+
.isGasAndPriorityFeeLimitingEnabled(true)
16771678
.build());
16781679

16791680
assertThat(commandOutput.toString(UTF_8)).isEmpty();

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
@Value.Style(allParameters = true)
2525
public abstract class ApiConfiguration {
2626

27-
public static final long DEFAULT_LOWER_BOUND_PRIORITY_FEE_COEFFICIENT = 0L;
28-
public static final long DEFAULT_UPPER_BOUND_PRIORITY_FEE_COEFFICIENT = Long.MAX_VALUE;
27+
public static final long DEFAULT_LOWER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT = 0L;
28+
public static final long DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT = Long.MAX_VALUE;
2929

3030
@Value.Default
3131
public long getGasPriceBlocks() {
@@ -64,17 +64,17 @@ public Long getGasCap() {
6464
}
6565

6666
@Value.Default
67-
public boolean isPriorityFeeLimitingEnabled() {
67+
public boolean isGasAndPriorityFeeLimitingEnabled() {
6868
return false;
6969
}
7070

7171
@Value.Default
72-
public Long getLowerBoundPriorityFeeCoefficient() {
73-
return DEFAULT_LOWER_BOUND_PRIORITY_FEE_COEFFICIENT;
72+
public Long getLowerBoundGasAndPriorityFeeCoefficient() {
73+
return DEFAULT_LOWER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT;
7474
}
7575

7676
@Value.Default
77-
public Long getUpperBoundPriorityFeeCoefficient() {
78-
return DEFAULT_UPPER_BOUND_PRIORITY_FEE_COEFFICIENT;
77+
public Long getUpperBoundGasAndPriorityFeeCoefficient() {
78+
return DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT;
7979
}
8080
}

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public List<Wei> computeRewards(final List<Double> rewardPercentiles, final Bloc
218218

219219
// If the priority fee boundary is set, return the bounded rewards. Otherwise, return the real
220220
// rewards.
221-
if (apiConfiguration.isPriorityFeeLimitingEnabled()) {
221+
if (apiConfiguration.isGasAndPriorityFeeLimitingEnabled()) {
222222
return boundRewards(realRewards);
223223
} else {
224224
return realRewards;
@@ -263,9 +263,13 @@ private List<Wei> calculateRewards(
263263
private List<Wei> boundRewards(final List<Wei> rewards) {
264264
Wei minPriorityFee = miningCoordinator.getMinPriorityFeePerGas();
265265
Wei lowerBound =
266-
minPriorityFee.multiply(apiConfiguration.getLowerBoundPriorityFeeCoefficient()).divide(100);
266+
minPriorityFee
267+
.multiply(apiConfiguration.getLowerBoundGasAndPriorityFeeCoefficient())
268+
.divide(100);
267269
Wei upperBound =
268-
minPriorityFee.multiply(apiConfiguration.getUpperBoundPriorityFeeCoefficient()).divide(100);
270+
minPriorityFee
271+
.multiply(apiConfiguration.getUpperBoundGasAndPriorityFeeCoefficient())
272+
.divide(100);
269273

270274
return rewards.stream().map(reward -> boundReward(reward, lowerBound, upperBound)).toList();
271275
}
@@ -279,19 +283,9 @@ private List<Wei> boundRewards(final List<Wei> rewards) {
279283
* @return The bounded reward.
280284
*/
281285
private Wei boundReward(final Wei reward, final Wei lowerBound, final Wei upperBound) {
282-
283-
// If the reward is less than the lower bound, return the lower bound.
284-
if (reward.compareTo(lowerBound) <= 0) {
285-
return lowerBound;
286-
}
287-
288-
// If the reward is greater than the upper bound, return the upper bound.
289-
if (reward.compareTo(upperBound) > 0) {
290-
return upperBound;
291-
}
292-
293-
// If the reward is within the bounds, return the reward as is.
294-
return reward;
286+
return reward.compareTo(lowerBound) <= 0
287+
? lowerBound
288+
: reward.compareTo(upperBound) >= 0 ? upperBound : reward;
295289
}
296290

297291
private List<Long> calculateTransactionsGasUsed(final Block block) {

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPrice.java

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
1616

17+
import org.hyperledger.besu.datatypes.Wei;
18+
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
1719
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
1820
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
1921
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
@@ -22,22 +24,29 @@
2224
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
2325
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
2426

27+
import java.util.Optional;
2528
import java.util.function.Supplier;
2629

2730
public class EthGasPrice implements JsonRpcMethod {
2831

2932
private final Supplier<BlockchainQueries> blockchain;
3033
private final MiningCoordinator miningCoordinator;
34+
private final ApiConfiguration apiConfiguration;
3135

3236
public EthGasPrice(
33-
final BlockchainQueries blockchain, final MiningCoordinator miningCoordinator) {
34-
this(() -> blockchain, miningCoordinator);
37+
final BlockchainQueries blockchain,
38+
final MiningCoordinator miningCoordinator,
39+
final ApiConfiguration apiConfiguration) {
40+
this(() -> blockchain, miningCoordinator, apiConfiguration);
3541
}
3642

3743
public EthGasPrice(
38-
final Supplier<BlockchainQueries> blockchain, final MiningCoordinator miningCoordinator) {
44+
final Supplier<BlockchainQueries> blockchain,
45+
final MiningCoordinator miningCoordinator,
46+
final ApiConfiguration apiConfiguration) {
3947
this.blockchain = blockchain;
4048
this.miningCoordinator = miningCoordinator;
49+
this.apiConfiguration = apiConfiguration;
4150
}
4251

4352
@Override
@@ -48,11 +57,37 @@ public String getName() {
4857
@Override
4958
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
5059
return new JsonRpcSuccessResponse(
51-
requestContext.getRequest().getId(),
52-
blockchain
53-
.get()
54-
.gasPrice()
55-
.map(Quantity::create)
56-
.orElseGet(() -> Quantity.create(miningCoordinator.getMinTransactionGasPrice())));
60+
requestContext.getRequest().getId(), Quantity.create(calculateGasPrice()));
61+
}
62+
63+
private Wei calculateGasPrice() {
64+
Wei gasPrice = getGasPrice().orElseGet(miningCoordinator::getMinTransactionGasPrice);
65+
return isGasPriceLimitingEnabled() ? limitGasPrice(gasPrice) : gasPrice;
66+
}
67+
68+
private Optional<Wei> getGasPrice() {
69+
return blockchain.get().gasPrice().map(Wei::of);
70+
}
71+
72+
private boolean isGasPriceLimitingEnabled() {
73+
return apiConfiguration.isGasAndPriorityFeeLimitingEnabled();
74+
}
75+
76+
private Wei limitGasPrice(final Wei gasPrice) {
77+
Wei minTransactionGasPrice = miningCoordinator.getMinTransactionGasPrice();
78+
Wei lowerBound =
79+
calculateBound(
80+
minTransactionGasPrice, apiConfiguration.getLowerBoundGasAndPriorityFeeCoefficient());
81+
Wei upperBound =
82+
calculateBound(
83+
minTransactionGasPrice, apiConfiguration.getUpperBoundGasAndPriorityFeeCoefficient());
84+
85+
return gasPrice.compareTo(lowerBound) <= 0
86+
? lowerBound
87+
: gasPrice.compareTo(upperBound) >= 0 ? upperBound : gasPrice;
88+
}
89+
90+
private Wei calculateBound(final Wei price, final long coefficient) {
91+
return price.multiply(coefficient).divide(100);
5792
}
5893
}

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ protected Map<String, JsonRpcMethod> create() {
174174
new EthMining(miningCoordinator),
175175
new EthCoinbase(miningCoordinator),
176176
new EthProtocolVersion(supportedCapabilities),
177-
new EthGasPrice(blockchainQueries, miningCoordinator),
177+
new EthGasPrice(blockchainQueries, miningCoordinator, apiConfiguration),
178178
new EthGetWork(miningCoordinator),
179179
new EthSubmitWork(miningCoordinator),
180180
new EthHashrate(miningCoordinator),

ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistoryTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,9 @@ public void shouldBoundRewardsCorrectly() {
174174

175175
ApiConfiguration apiConfiguration =
176176
ImmutableApiConfiguration.builder()
177-
.isPriorityFeeLimitingEnabled(true)
178-
.lowerBoundPriorityFeeCoefficient(200L) // Min reward = Wei.One * 200L / 100 = 2.0
179-
.upperBoundPriorityFeeCoefficient(500L)
177+
.isGasAndPriorityFeeLimitingEnabled(true)
178+
.lowerBoundGasAndPriorityFeeCoefficient(200L) // Min reward = Wei.One * 200L / 100 = 2.0
179+
.upperBoundGasAndPriorityFeeCoefficient(500L)
180180
.build(); // Max reward = Wei.One * 500L / 100 = 5.0
181181

182182
EthFeeHistory ethFeeHistory =

0 commit comments

Comments
 (0)