Skip to content

Commit

Permalink
Include current chain head block when computing eth_maxPriorityFeePerGas
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio Di Fabio <[email protected]>
  • Loading branch information
fab-10 committed Aug 19, 2024
1 parent 0dffe63 commit 7bd9e1d
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 80 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

### Additions and Improvements
- Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461)
- Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485)

### Bug fixes
- Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,15 @@ public DataFetcher<Optional<BigInteger>> getChainIdDataFetcher() {
*
* <p>The DataFetcher is a functional interface. It has a single method that takes a
* DataFetchingEnvironment object as input and returns the maximum priority fee per gas as a Wei
* object. If the maximum priority fee per gas is not available, it returns Wei.ZERO.
* object.
*
* @return a DataFetcher that fetches the maximum priority fee per gas of the Ethereum node
*/
public DataFetcher<Wei> getMaxPriorityFeePerGasDataFetcher() {
return dataFetchingEnvironment -> {
final BlockchainQueries blockchainQuery =
dataFetchingEnvironment.getGraphQlContext().get(GraphQLContextType.BLOCKCHAIN_QUERIES);
return blockchainQuery.gasPriorityFee().orElse(Wei.ZERO);
return blockchainQuery.gasPriorityFee();
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,13 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;

import java.util.Optional;

public class EthMaxPriorityFeePerGas implements JsonRpcMethod {

private final BlockchainQueries blockchainQueries;
private final MiningCoordinator miningCoordinator;

public EthMaxPriorityFeePerGas(
final BlockchainQueries blockchainQueries, final MiningCoordinator miningCoordinator) {
public EthMaxPriorityFeePerGas(final BlockchainQueries blockchainQueries) {
this.blockchainQueries = blockchainQueries;
this.miningCoordinator = miningCoordinator;
}

@Override
Expand All @@ -48,7 +42,6 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
}

private Wei fetchAndLimitPriorityFeePerGas() {
final Optional<Wei> gasPrice = blockchainQueries.gasPriorityFee();
return gasPrice.orElseGet(miningCoordinator::getMinPriorityFeePerGas);
return blockchainQueries.gasPriorityFee();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,6 @@ protected Map<String, JsonRpcMethod> create() {
new EthGetMinerDataByBlockHash(blockchainQueries, protocolSchedule),
new EthGetMinerDataByBlockNumber(blockchainQueries, protocolSchedule),
new EthBlobBaseFee(blockchainQueries.getBlockchain(), protocolSchedule),
new EthMaxPriorityFeePerGas(blockchainQueries, miningCoordinator));
new EthMaxPriorityFeePerGas(blockchainQueries));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
Expand Down Expand Up @@ -1006,7 +1005,7 @@ public Wei gasPrice() {
.sorted()
.toArray(Wei[]::new);

return (gasCollection == null || gasCollection.length == 0)
return gasCollection.length == 0
? gasPriceLowerBound(chainHeadHeader, nextBlockFeeMarket)
: UInt256s.max(
gasPriceLowerBound(chainHeadHeader, nextBlockFeeMarket),
Expand Down Expand Up @@ -1045,31 +1044,39 @@ private Wei gasPriceLowerBound(
return minGasPrice;
}

public Optional<Wei> gasPriorityFee() {
final long blockHeight = headBlockNumber();
final BigInteger[] gasCollection =
LongStream.range(Math.max(0, blockHeight - apiConfig.getGasPriceBlocks()), blockHeight)
.mapToObj(
l ->
blockchain
.getBlockByNumber(l)
.map(Block::getBody)
.map(BlockBody::getTransactions)
.orElseThrow(
() -> new IllegalStateException("Could not retrieve block #" + l)))
public Wei gasPriorityFee() {
final Block chainHeadBlock = blockchain.getChainHeadBlock();
final long blockHeight = chainHeadBlock.getHeader().getNumber();

final Wei[] gasCollection =
Stream.concat(
LongStream.range(
Math.max(0, blockHeight - apiConfig.getGasPriceBlocks() + 1), blockHeight)
.mapToObj(
l ->
blockchain
.getBlockByNumber(l)
.orElseThrow(
() ->
new IllegalStateException(
"Could not retrieve block #" + l))),
Stream.of(chainHeadBlock))
.map(Block::getBody)
.map(BlockBody::getTransactions)
.flatMap(Collection::stream)
.filter(t -> t.getMaxPriorityFeePerGas().isPresent())
.map(t -> t.getMaxPriorityFeePerGas().get().toBigInteger())
.sorted(BigInteger::compareTo)
.toArray(BigInteger[]::new);
return (gasCollection.length == 0)
? Optional.empty()
: Optional.of(
Wei.of(
gasCollection[
Math.min(
gasCollection.length - 1,
(int) ((gasCollection.length) * apiConfig.getGasPriceFraction()))]));
.map(t -> t.getMaxPriorityFeePerGas().get())
.sorted()
.toArray(Wei[]::new);

return gasCollection.length == 0
? miningParameters.getMinPriorityFeePerGas()
: UInt256s.max(
miningParameters.getMinPriorityFeePerGas(),
gasCollection[
Math.min(
gasCollection.length - 1,
(int) ((gasCollection.length) * apiConfig.getGasPriceFraction()))]);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ private void mockBlockchain(
}

when(blockchain.getChainHeadBlock()).thenReturn(blocksByNumber.get(chainHeadBlockNumber));
if (chainHeadBlockNumber > 1) {
if (chainHeadBlockNumber > 0) {
when(blockchain.getBlockByNumber(anyLong()))
.thenAnswer(
invocation -> Optional.of(blocksByNumber.get(invocation.getArgument(0, Long.class))));
Expand Down
Loading

0 comments on commit 7bd9e1d

Please sign in to comment.