mirror of
https://github.com/vacp2p/status-linea-besu.git
synced 2026-01-09 22:07:59 -05:00
Make eth_gasPrice aware of the base fee market (#7102)
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
|
||||
### Bug fixes
|
||||
- Fix parsing `gasLimit` parameter when its value is > `Long.MAX_VALUE` [#7116](https://github.com/hyperledger/besu/pull/7116)
|
||||
- Make `eth_gasPrice` aware of the base fee market [#7102](https://github.com/hyperledger/besu/pull/7102)
|
||||
- Skip validation of withdrawals when importing BFT blocks since withdrawals don't apply to BFT chains [#7115](https://github.com/hyperledger/besu/pull/7115)
|
||||
|
||||
## 24.5.1
|
||||
|
||||
@@ -106,7 +106,6 @@ import org.hyperledger.besu.ethereum.privacy.PrivateTransactionObserver;
|
||||
import org.hyperledger.besu.ethereum.storage.StorageProvider;
|
||||
import org.hyperledger.besu.ethereum.stratum.StratumServer;
|
||||
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.ethstats.EthStatsService;
|
||||
import org.hyperledger.besu.ethstats.util.EthStatsConnectOptions;
|
||||
import org.hyperledger.besu.metrics.MetricsService;
|
||||
@@ -725,14 +724,17 @@ public class RunnerBuilder {
|
||||
|
||||
final TransactionPool transactionPool = besuController.getTransactionPool();
|
||||
final MiningCoordinator miningCoordinator = besuController.getMiningCoordinator();
|
||||
final MiningParameters miningParameters = besuController.getMiningParameters();
|
||||
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
protocolSchedule,
|
||||
context.getBlockchain(),
|
||||
context.getWorldStateArchive(),
|
||||
Optional.of(dataDir.resolve(CACHE_PATH)),
|
||||
Optional.of(besuController.getProtocolManager().ethContext().getScheduler()),
|
||||
apiConfiguration);
|
||||
apiConfiguration,
|
||||
miningParameters);
|
||||
|
||||
final PrivacyParameters privacyParameters = besuController.getPrivacyParameters();
|
||||
|
||||
@@ -749,7 +751,6 @@ public class RunnerBuilder {
|
||||
|
||||
final P2PNetwork peerNetwork = networkRunner.getNetwork();
|
||||
|
||||
final MiningParameters miningParameters = besuController.getMiningParameters();
|
||||
Optional<StratumServer> stratumServer = Optional.empty();
|
||||
|
||||
if (miningParameters.isStratumMiningEnabled()) {
|
||||
@@ -957,10 +958,7 @@ public class RunnerBuilder {
|
||||
rpcEndpointServiceImpl);
|
||||
|
||||
createLogsSubscriptionService(
|
||||
context.getBlockchain(),
|
||||
context.getWorldStateArchive(),
|
||||
subscriptionManager,
|
||||
privacyParameters);
|
||||
context.getBlockchain(), subscriptionManager, privacyParameters, blockchainQueries);
|
||||
|
||||
createNewBlockHeadersSubscriptionService(
|
||||
context.getBlockchain(), blockchainQueries, subscriptionManager);
|
||||
@@ -1273,15 +1271,12 @@ public class RunnerBuilder {
|
||||
|
||||
private void createLogsSubscriptionService(
|
||||
final Blockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final SubscriptionManager subscriptionManager,
|
||||
final PrivacyParameters privacyParameters) {
|
||||
final PrivacyParameters privacyParameters,
|
||||
final BlockchainQueries blockchainQueries) {
|
||||
|
||||
Optional<PrivacyQueries> privacyQueries = Optional.empty();
|
||||
if (privacyParameters.isEnabled()) {
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
blockchain, worldStateArchive, Optional.empty(), Optional.empty(), apiConfiguration);
|
||||
privacyQueries =
|
||||
Optional.of(
|
||||
new PrivacyQueries(
|
||||
|
||||
@@ -327,6 +327,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
Suppliers.memoize(this::readGenesisConfigFile);
|
||||
private final Supplier<GenesisConfigOptions> genesisConfigOptionsSupplier =
|
||||
Suppliers.memoize(this::readGenesisConfigOptions);
|
||||
private final Supplier<MiningParameters> miningParametersSupplier =
|
||||
Suppliers.memoize(this::getMiningParameters);
|
||||
|
||||
private RocksDBPlugin rocksDBPlugin;
|
||||
|
||||
@@ -898,7 +900,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
private Collection<EnodeURL> staticNodes;
|
||||
private BesuController besuController;
|
||||
private BesuConfigurationImpl pluginCommonConfiguration;
|
||||
private MiningParameters miningParameters;
|
||||
|
||||
private BesuComponent besuComponent;
|
||||
private final Supplier<ObservableMetricsSystem> metricsSystem =
|
||||
@@ -1351,8 +1352,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
TraceService.class,
|
||||
new TraceServiceImpl(
|
||||
new BlockchainQueries(
|
||||
besuController.getProtocolSchedule(),
|
||||
besuController.getProtocolContext().getBlockchain(),
|
||||
besuController.getProtocolContext().getWorldStateArchive()),
|
||||
besuController.getProtocolContext().getWorldStateArchive(),
|
||||
miningParametersSupplier.get()),
|
||||
besuController.getProtocolSchedule()));
|
||||
|
||||
besuController.getAdditionalPluginServices().appendPluginServices(besuPluginContext);
|
||||
@@ -1374,7 +1377,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
"--privacy-marker-transaction-signing-key-file can not be used in conjunction with a plugin that specifies a PrivateMarkerTransactionFactory");
|
||||
}
|
||||
|
||||
if (Wei.ZERO.compareTo(getMiningParameters().getMinTransactionGasPrice()) < 0
|
||||
if (Wei.ZERO.compareTo(miningParametersSupplier.get().getMinTransactionGasPrice()) < 0
|
||||
&& (privacyOptionGroup.privateMarkerTransactionSigningKeyPath == null
|
||||
&& (privacyPluginService == null
|
||||
|| privacyPluginService.getPrivateMarkerTransactionFactory() == null))) {
|
||||
@@ -1755,7 +1758,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
unstableIpcOptions.isEnabled(),
|
||||
unstableIpcOptions.getIpcPath(),
|
||||
unstableIpcOptions.getRpcIpcApis());
|
||||
apiConfiguration = apiConfigurationOptions.apiConfiguration(getMiningParameters());
|
||||
apiConfiguration = apiConfigurationOptions.apiConfiguration();
|
||||
dataStorageConfiguration = getDataStorageConfiguration();
|
||||
// hostsWhitelist is a hidden option. If it is specified, add the list to hostAllowlist
|
||||
if (!hostsWhitelist.isEmpty()) {
|
||||
@@ -1844,7 +1847,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
dataDir(),
|
||||
dataDir().resolve(DATABASE_PATH),
|
||||
getDataStorageConfiguration(),
|
||||
getMiningParameters());
|
||||
miningParametersSupplier.get());
|
||||
final KeyValueStorageProvider storageProvider = keyValueStorageProvider(keyValueStorageName);
|
||||
return controllerBuilderFactory
|
||||
.fromEthNetworkConfig(updateNetworkConfig(network), getDefaultSyncModeIfNotSet())
|
||||
@@ -1853,7 +1856,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
.networkConfiguration(unstableNetworkingOptions.toDomainObject())
|
||||
.dataDirectory(dataDir())
|
||||
.dataStorageConfiguration(getDataStorageConfiguration())
|
||||
.miningParameters(getMiningParameters())
|
||||
.miningParameters(miningParametersSupplier.get())
|
||||
.transactionPoolConfiguration(buildTransactionPoolConfiguration())
|
||||
.nodeKey(new NodeKey(securityModule()))
|
||||
.metricsSystem(metricsSystem.get())
|
||||
@@ -1864,7 +1867,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
.isRevertReasonEnabled(isRevertReasonEnabled)
|
||||
.storageProvider(storageProvider)
|
||||
.gasLimitCalculator(
|
||||
getMiningParameters().getTargetGasLimit().isPresent()
|
||||
miningParametersSupplier.get().getTargetGasLimit().isPresent()
|
||||
? new FrontierTargetingGasLimitCalculator()
|
||||
: GasLimitCalculator.constant())
|
||||
.requiredBlocks(requiredBlocks)
|
||||
@@ -2157,14 +2160,17 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
txPoolConfBuilder.priceBump(Percentage.ZERO);
|
||||
}
|
||||
|
||||
if (getMiningParameters().getMinTransactionGasPrice().equals(Wei.ZERO)
|
||||
if (miningParametersSupplier.get().getMinTransactionGasPrice().equals(Wei.ZERO)
|
||||
&& !transactionPoolOptions.isPriceBumpSet(commandLine)) {
|
||||
logger.info(
|
||||
"Forcing price bump for transaction replacement to 0, since min-gas-price is set to 0");
|
||||
txPoolConfBuilder.priceBump(Percentage.ZERO);
|
||||
}
|
||||
|
||||
if (getMiningParameters().getMinTransactionGasPrice().lessThan(txPoolConf.getMinGasPrice())) {
|
||||
if (miningParametersSupplier
|
||||
.get()
|
||||
.getMinTransactionGasPrice()
|
||||
.lessThan(txPoolConf.getMinGasPrice())) {
|
||||
if (transactionPoolOptions.isMinGasPriceSet(commandLine)) {
|
||||
throw new ParameterException(
|
||||
commandLine, "tx-pool-min-gas-price cannot be greater than the value of min-gas-price");
|
||||
@@ -2175,9 +2181,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
// the user of the change
|
||||
logger.warn(
|
||||
"Forcing tx-pool-min-gas-price="
|
||||
+ getMiningParameters().getMinTransactionGasPrice().toDecimalString()
|
||||
+ miningParametersSupplier.get().getMinTransactionGasPrice().toDecimalString()
|
||||
+ ", since it cannot be greater than the value of min-gas-price");
|
||||
txPoolConfBuilder.minGasPrice(getMiningParameters().getMinTransactionGasPrice());
|
||||
txPoolConfBuilder.minGasPrice(miningParametersSupplier.get().getMinTransactionGasPrice());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2185,13 +2191,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
|
||||
private MiningParameters getMiningParameters() {
|
||||
if (miningParameters == null) {
|
||||
miningOptions.setTransactionSelectionService(transactionSelectionServiceImpl);
|
||||
miningParameters = miningOptions.toDomainObject();
|
||||
getGenesisBlockPeriodSeconds(genesisConfigOptionsSupplier.get())
|
||||
.ifPresent(miningParameters::setBlockPeriodSeconds);
|
||||
initMiningParametersMetrics(miningParameters);
|
||||
}
|
||||
miningOptions.setTransactionSelectionService(transactionSelectionServiceImpl);
|
||||
final var miningParameters = miningOptions.toDomainObject();
|
||||
getGenesisBlockPeriodSeconds(genesisConfigOptionsSupplier.get())
|
||||
.ifPresent(miningParameters::setBlockPeriodSeconds);
|
||||
initMiningParametersMetrics(miningParameters);
|
||||
return miningParameters;
|
||||
}
|
||||
|
||||
@@ -2567,8 +2571,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
effectivePorts, metricsOptionGroup.metricsPort, metricsOptionGroup.isMetricsEnabled);
|
||||
addPortIfEnabled(
|
||||
effectivePorts,
|
||||
getMiningParameters().getStratumPort(),
|
||||
getMiningParameters().isStratumMiningEnabled());
|
||||
miningParametersSupplier.get().getStratumPort(),
|
||||
miningParametersSupplier.get().isStratumMiningEnabled());
|
||||
return effectivePorts;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ package org.hyperledger.besu.cli.options.stable;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import org.hyperledger.besu.cli.util.CommandLineUtils;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
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;
|
||||
@@ -119,17 +119,14 @@ public class ApiConfigurationOptions {
|
||||
/**
|
||||
* Creates an ApiConfiguration based on the provided options.
|
||||
*
|
||||
* @param miningParameters The mining parameters
|
||||
* @return An ApiConfiguration instance
|
||||
*/
|
||||
public ApiConfiguration apiConfiguration(final MiningParameters miningParameters) {
|
||||
public ApiConfiguration apiConfiguration() {
|
||||
var builder =
|
||||
ImmutableApiConfiguration.builder()
|
||||
.gasPriceBlocks(apiGasPriceBlocks)
|
||||
.gasPricePercentile(apiGasPricePercentile)
|
||||
.gasPriceMinSupplier(
|
||||
miningParameters.getMinTransactionGasPrice().getAsBigInteger()::longValueExact)
|
||||
.gasPriceMax(apiGasPriceMax)
|
||||
.gasPriceMax(Wei.of(apiGasPriceMax))
|
||||
.maxLogsRange(rpcMaxLogsRange)
|
||||
.gasCap(rpcGasCap)
|
||||
.isGasAndPriorityFeeLimitingEnabled(apiGasAndPriorityFeeLimitingEnabled)
|
||||
|
||||
@@ -731,7 +731,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
createSubProtocolConfiguration(ethProtocolManager, maybeSnapProtocolManager);
|
||||
|
||||
final JsonRpcMethods additionalJsonRpcMethodFactory =
|
||||
createAdditionalJsonRpcMethodFactory(protocolContext);
|
||||
createAdditionalJsonRpcMethodFactory(protocolContext, protocolSchedule, miningParameters);
|
||||
|
||||
if (dataStorageConfiguration.getUnstable().getBonsaiLimitTrieLogsEnabled()
|
||||
&& DataStorageFormat.BONSAI.equals(dataStorageConfiguration.getDataStorageFormat())) {
|
||||
@@ -884,10 +884,14 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
* Create additional json rpc method factory json rpc methods.
|
||||
*
|
||||
* @param protocolContext the protocol context
|
||||
* @param protocolSchedule the protocol schedule
|
||||
* @param miningParameters the mining parameters
|
||||
* @return the json rpc methods
|
||||
*/
|
||||
protected JsonRpcMethods createAdditionalJsonRpcMethodFactory(
|
||||
final ProtocolContext protocolContext) {
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final MiningParameters miningParameters) {
|
||||
return apis -> Collections.emptyMap();
|
||||
}
|
||||
|
||||
|
||||
@@ -72,8 +72,10 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder {
|
||||
|
||||
@Override
|
||||
protected JsonRpcMethods createAdditionalJsonRpcMethodFactory(
|
||||
final ProtocolContext protocolContext) {
|
||||
return new CliqueJsonRpcMethods(protocolContext);
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final MiningParameters miningParameters) {
|
||||
return new CliqueJsonRpcMethods(protocolContext, protocolSchedule, miningParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -204,10 +204,12 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde
|
||||
|
||||
@Override
|
||||
protected JsonRpcMethods createAdditionalJsonRpcMethodFactory(
|
||||
final ProtocolContext protocolContext) {
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final MiningParameters miningParameters) {
|
||||
return besuControllerBuilderSchedule
|
||||
.get(0L)
|
||||
.createAdditionalJsonRpcMethodFactory(protocolContext);
|
||||
.createAdditionalJsonRpcMethodFactory(protocolContext, protocolSchedule, miningParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -111,8 +111,10 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder {
|
||||
|
||||
@Override
|
||||
protected JsonRpcMethods createAdditionalJsonRpcMethodFactory(
|
||||
final ProtocolContext protocolContext) {
|
||||
return new IbftJsonRpcMethods(protocolContext);
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final MiningParameters miningParameters) {
|
||||
return new IbftJsonRpcMethods(protocolContext, protocolSchedule, miningParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -130,10 +130,15 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
|
||||
|
||||
@Override
|
||||
protected JsonRpcMethods createAdditionalJsonRpcMethodFactory(
|
||||
final ProtocolContext protocolContext) {
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final MiningParameters miningParameters) {
|
||||
|
||||
return new QbftJsonRpcMethods(
|
||||
protocolContext, createReadOnlyValidatorProvider(protocolContext.getBlockchain()));
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
miningParameters,
|
||||
createReadOnlyValidatorProvider(protocolContext.getBlockchain()));
|
||||
}
|
||||
|
||||
private ValidatorProvider createReadOnlyValidatorProvider(final Blockchain blockchain) {
|
||||
|
||||
@@ -32,6 +32,8 @@ import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -99,10 +101,13 @@ public class QbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuil
|
||||
@Test
|
||||
public void missingTransactionValidatorProviderThrowsError() {
|
||||
final ProtocolContext protocolContext = mock(ProtocolContext.class);
|
||||
final ProtocolSchedule protocolSchedule = mock(ProtocolSchedule.class);
|
||||
when(protocolContext.getBlockchain()).thenReturn(mock(MutableBlockchain.class));
|
||||
|
||||
assertThatThrownBy(
|
||||
() -> bftBesuControllerBuilder.createAdditionalJsonRpcMethodFactory(protocolContext))
|
||||
() ->
|
||||
bftBesuControllerBuilder.createAdditionalJsonRpcMethodFactory(
|
||||
protocolContext, protocolSchedule, MiningParameters.newDefault()))
|
||||
.isInstanceOf(NullPointerException.class)
|
||||
.hasMessage("transactionValidatorProvider should have been initialised");
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.evm.log.Log;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldView;
|
||||
@@ -74,7 +75,12 @@ class TraceServiceImplTest {
|
||||
blockchainSetupUtil.importAllBlocks();
|
||||
blockchain = blockchainSetupUtil.getBlockchain();
|
||||
worldStateArchive = blockchainSetupUtil.getWorldArchive();
|
||||
blockchainQueries = new BlockchainQueries(blockchain, worldStateArchive);
|
||||
blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
blockchainSetupUtil.getProtocolSchedule(),
|
||||
blockchain,
|
||||
worldStateArchive,
|
||||
MiningParameters.newDefault());
|
||||
traceService =
|
||||
new TraceServiceImpl(blockchainQueries, blockchainSetupUtil.getProtocolSchedule());
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.methods.ApiGroupJsonRpcMethods;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -38,14 +40,23 @@ import java.util.Map;
|
||||
/** The Clique json rpc methods. */
|
||||
public class CliqueJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
private final ProtocolContext context;
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final MiningParameters miningParameters;
|
||||
|
||||
/**
|
||||
* Instantiates a new Clique json rpc methods.
|
||||
*
|
||||
* @param context the context
|
||||
* @param context the protocol context
|
||||
* @param protocolSchedule the protocol schedule
|
||||
* @param miningParameters the mining parameters
|
||||
*/
|
||||
public CliqueJsonRpcMethods(final ProtocolContext context) {
|
||||
public CliqueJsonRpcMethods(
|
||||
final ProtocolContext context,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final MiningParameters miningParameters) {
|
||||
this.context = context;
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.miningParameters = miningParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,7 +69,7 @@ public class CliqueJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
final MutableBlockchain blockchain = context.getBlockchain();
|
||||
final WorldStateArchive worldStateArchive = context.getWorldStateArchive();
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(blockchain, worldStateArchive);
|
||||
new BlockchainQueries(protocolSchedule, blockchain, worldStateArchive, miningParameters);
|
||||
final ValidatorProvider validatorProvider =
|
||||
context.getConsensusContext(CliqueContext.class).getValidatorProvider();
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.methods.ApiGroupJsonRpcMethods;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -39,14 +41,23 @@ import java.util.Map;
|
||||
public class IbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
|
||||
private final ProtocolContext context;
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final MiningParameters miningParameters;
|
||||
|
||||
/**
|
||||
* Instantiates a new Ibft json rpc methods.
|
||||
*
|
||||
* @param context the context
|
||||
* @param context the protocol context
|
||||
* @param protocolSchedule the protocol schedule
|
||||
* @param miningParameters the mining parameters
|
||||
*/
|
||||
public IbftJsonRpcMethods(final ProtocolContext context) {
|
||||
public IbftJsonRpcMethods(
|
||||
final ProtocolContext context,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final MiningParameters miningParameters) {
|
||||
this.context = context;
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.miningParameters = miningParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,7 +69,8 @@ public class IbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
protected Map<String, JsonRpcMethod> create() {
|
||||
final MutableBlockchain blockchain = context.getBlockchain();
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(blockchain, context.getWorldStateArchive());
|
||||
new BlockchainQueries(
|
||||
protocolSchedule, blockchain, context.getWorldStateArchive(), miningParameters);
|
||||
final BftContext bftContext = context.getConsensusContext(BftContext.class);
|
||||
final BlockInterface blockInterface = bftContext.getBlockInterface();
|
||||
final ValidatorProvider validatorProvider =
|
||||
|
||||
@@ -28,6 +28,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.methods.ApiGroupJsonRpcMethods;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -36,17 +38,26 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
|
||||
private final ProtocolContext context;
|
||||
private final ValidatorProvider readOnlyValidatorProvider;
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final MiningParameters miningParameters;
|
||||
|
||||
/**
|
||||
* Instantiates a new Qbft json rpc methods.
|
||||
*
|
||||
* @param context the context
|
||||
* @param context the protocol context
|
||||
* @param protocolSchedule the protocol schedule
|
||||
* @param miningParameters the mining parameters
|
||||
* @param readOnlyValidatorProvider the read only validator provider
|
||||
*/
|
||||
public QbftJsonRpcMethods(
|
||||
final ProtocolContext context, final ValidatorProvider readOnlyValidatorProvider) {
|
||||
final ProtocolContext context,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final MiningParameters miningParameters,
|
||||
final ValidatorProvider readOnlyValidatorProvider) {
|
||||
this.context = context;
|
||||
this.readOnlyValidatorProvider = readOnlyValidatorProvider;
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.miningParameters = miningParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,7 +68,11 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
@Override
|
||||
protected Map<String, JsonRpcMethod> create() {
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(context.getBlockchain(), context.getWorldStateArchive());
|
||||
new BlockchainQueries(
|
||||
protocolSchedule,
|
||||
context.getBlockchain(),
|
||||
context.getWorldStateArchive(),
|
||||
miningParameters);
|
||||
final BftContext bftContext = context.getConsensusContext(BftContext.class);
|
||||
final BlockInterface blockInterface = bftContext.getBlockInterface();
|
||||
final ValidatorProvider validatorProvider = bftContext.getValidatorProvider();
|
||||
|
||||
@@ -89,7 +89,9 @@ public class JsonRpcTestMethodsFactory {
|
||||
final BlockImporter blockImporter = protocolSpec.getBlockImporter();
|
||||
blockImporter.importBlock(context, block, HeaderValidationMode.FULL);
|
||||
}
|
||||
this.blockchainQueries = new BlockchainQueries(blockchain, stateArchive);
|
||||
this.blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
protocolSchedule, blockchain, stateArchive, MiningParameters.newDefault());
|
||||
}
|
||||
|
||||
public JsonRpcTestMethodsFactory(
|
||||
@@ -101,7 +103,12 @@ public class JsonRpcTestMethodsFactory {
|
||||
this.blockchain = blockchain;
|
||||
this.stateArchive = stateArchive;
|
||||
this.context = context;
|
||||
this.blockchainQueries = new BlockchainQueries(blockchain, stateArchive);
|
||||
this.blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
importer.getProtocolSchedule(),
|
||||
blockchain,
|
||||
stateArchive,
|
||||
MiningParameters.newDefault());
|
||||
this.synchronizer = mock(Synchronizer.class);
|
||||
}
|
||||
|
||||
@@ -116,7 +123,12 @@ public class JsonRpcTestMethodsFactory {
|
||||
this.stateArchive = stateArchive;
|
||||
this.context = context;
|
||||
this.synchronizer = synchronizer;
|
||||
this.blockchainQueries = new BlockchainQueries(blockchain, stateArchive);
|
||||
this.blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
importer.getProtocolSchedule(),
|
||||
blockchain,
|
||||
stateArchive,
|
||||
MiningParameters.newDefault());
|
||||
}
|
||||
|
||||
public BlockchainQueries getBlockchainQueries() {
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.Difficulty;
|
||||
import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
|
||||
@@ -123,7 +124,11 @@ public class EthGetFilterChangesIntegrationTest {
|
||||
TransactionPoolConfiguration.DEFAULT);
|
||||
transactionPool.setEnabled();
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(blockchain, protocolContext.getWorldStateArchive());
|
||||
new BlockchainQueries(
|
||||
executionContext.getProtocolSchedule(),
|
||||
blockchain,
|
||||
protocolContext.getWorldStateArchive(),
|
||||
MiningParameters.newDefault());
|
||||
filterManager =
|
||||
new FilterManagerBuilder()
|
||||
.blockchainQueries(blockchainQueries)
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.Difficulty;
|
||||
import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
|
||||
@@ -123,7 +124,11 @@ public class EthGetFilterChangesIntegrationTest {
|
||||
TransactionPoolConfiguration.DEFAULT);
|
||||
transactionPool.setEnabled();
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(blockchain, protocolContext.getWorldStateArchive());
|
||||
new BlockchainQueries(
|
||||
executionContext.getProtocolSchedule(),
|
||||
blockchain,
|
||||
protocolContext.getWorldStateArchive(),
|
||||
MiningParameters.newDefault());
|
||||
filterManager =
|
||||
new FilterManagerBuilder()
|
||||
.blockchainQueries(blockchainQueries)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api;
|
||||
|
||||
import java.util.function.LongSupplier;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
|
||||
import org.immutables.value.Value;
|
||||
|
||||
@@ -36,14 +36,8 @@ public abstract class ApiConfiguration {
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
@Value.Auxiliary
|
||||
public LongSupplier getGasPriceMinSupplier() {
|
||||
return () -> 1_000_000_000L; // 1 GWei
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
public long getGasPriceMax() {
|
||||
return 500_000_000_000L; // 500 GWei
|
||||
public Wei getGasPriceMax() {
|
||||
return Wei.of(500_000_000_000L); // 500 GWei
|
||||
}
|
||||
|
||||
@Value.Derived
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.api.query.LogsQuery;
|
||||
import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
|
||||
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
|
||||
import org.hyperledger.besu.ethereum.core.LogWithMetadata;
|
||||
import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
@@ -117,17 +116,12 @@ public class GraphQLDataFetchers {
|
||||
};
|
||||
}
|
||||
|
||||
DataFetcher<Optional<Wei>> getGasPriceDataFetcher() {
|
||||
DataFetcher<Wei> getGasPriceDataFetcher() {
|
||||
return dataFetchingEnvironment -> {
|
||||
final GraphQLContext graphQLContext = dataFetchingEnvironment.getGraphQlContext();
|
||||
final BlockchainQueries blockchainQueries =
|
||||
graphQLContext.get(GraphQLContextType.BLOCKCHAIN_QUERIES);
|
||||
final MiningCoordinator miningCoordinator =
|
||||
graphQLContext.get(GraphQLContextType.MINING_COORDINATOR);
|
||||
return blockchainQueries
|
||||
.gasPrice()
|
||||
.map(Wei::of)
|
||||
.or(() -> Optional.of(miningCoordinator.getMinTransactionGasPrice()));
|
||||
return blockchainQueries.gasPrice();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -22,30 +22,15 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcRespon
|
||||
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;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class EthGasPrice implements JsonRpcMethod {
|
||||
|
||||
private final Supplier<BlockchainQueries> blockchain;
|
||||
private final MiningCoordinator miningCoordinator;
|
||||
private final BlockchainQueries blockchainQueries;
|
||||
private final ApiConfiguration apiConfiguration;
|
||||
|
||||
public EthGasPrice(
|
||||
final BlockchainQueries blockchain,
|
||||
final MiningCoordinator miningCoordinator,
|
||||
final ApiConfiguration apiConfiguration) {
|
||||
this(() -> blockchain, miningCoordinator, apiConfiguration);
|
||||
}
|
||||
|
||||
public EthGasPrice(
|
||||
final Supplier<BlockchainQueries> blockchain,
|
||||
final MiningCoordinator miningCoordinator,
|
||||
final ApiConfiguration apiConfiguration) {
|
||||
this.blockchain = blockchain;
|
||||
this.miningCoordinator = miningCoordinator;
|
||||
final BlockchainQueries blockchainQueries, final ApiConfiguration apiConfiguration) {
|
||||
this.blockchainQueries = blockchainQueries;
|
||||
this.apiConfiguration = apiConfiguration;
|
||||
}
|
||||
|
||||
@@ -61,30 +46,26 @@ public class EthGasPrice implements JsonRpcMethod {
|
||||
}
|
||||
|
||||
private Wei calculateGasPrice() {
|
||||
Wei gasPrice = getGasPrice().orElseGet(miningCoordinator::getMinTransactionGasPrice);
|
||||
final Wei gasPrice = blockchainQueries.gasPrice();
|
||||
return isGasPriceLimitingEnabled() ? limitGasPrice(gasPrice) : gasPrice;
|
||||
}
|
||||
|
||||
private Optional<Wei> getGasPrice() {
|
||||
return blockchain.get().gasPrice().map(Wei::of);
|
||||
}
|
||||
|
||||
private boolean isGasPriceLimitingEnabled() {
|
||||
return apiConfiguration.isGasAndPriorityFeeLimitingEnabled();
|
||||
}
|
||||
|
||||
private Wei limitGasPrice(final Wei gasPrice) {
|
||||
Wei minTransactionGasPrice = miningCoordinator.getMinTransactionGasPrice();
|
||||
Wei lowerBound =
|
||||
final Wei lowerBoundGasPrice = blockchainQueries.gasPriceLowerBound();
|
||||
final Wei forcedLowerBound =
|
||||
calculateBound(
|
||||
minTransactionGasPrice, apiConfiguration.getLowerBoundGasAndPriorityFeeCoefficient());
|
||||
Wei upperBound =
|
||||
lowerBoundGasPrice, apiConfiguration.getLowerBoundGasAndPriorityFeeCoefficient());
|
||||
final Wei forcedUpperBound =
|
||||
calculateBound(
|
||||
minTransactionGasPrice, apiConfiguration.getUpperBoundGasAndPriorityFeeCoefficient());
|
||||
lowerBoundGasPrice, apiConfiguration.getUpperBoundGasAndPriorityFeeCoefficient());
|
||||
|
||||
return gasPrice.compareTo(lowerBound) <= 0
|
||||
? lowerBound
|
||||
: gasPrice.compareTo(upperBound) >= 0 ? upperBound : gasPrice;
|
||||
return gasPrice.compareTo(forcedLowerBound) <= 0
|
||||
? forcedLowerBound
|
||||
: gasPrice.compareTo(forcedUpperBound) >= 0 ? forcedUpperBound : gasPrice;
|
||||
}
|
||||
|
||||
private Wei calculateBound(final Wei price, final long coefficient) {
|
||||
|
||||
@@ -175,7 +175,7 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
new EthMining(miningCoordinator),
|
||||
new EthCoinbase(miningCoordinator),
|
||||
new EthProtocolVersion(supportedCapabilities),
|
||||
new EthGasPrice(blockchainQueries, miningCoordinator, apiConfiguration),
|
||||
new EthGasPrice(blockchainQueries, apiConfiguration),
|
||||
new EthGetWork(miningCoordinator),
|
||||
new EthSubmitWork(miningCoordinator),
|
||||
new EthHashrate(miningCoordinator),
|
||||
|
||||
@@ -30,12 +30,15 @@ import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.LogWithMetadata;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.MutableWorldState;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.log.LogsBloomFilter;
|
||||
@@ -60,49 +63,77 @@ import java.util.stream.LongStream;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.apache.tuweni.units.bigints.UInt256s;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class BlockchainQueries {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BlockchainQueries.class);
|
||||
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final WorldStateArchive worldStateArchive;
|
||||
private final Blockchain blockchain;
|
||||
private final Optional<Path> cachePath;
|
||||
private final Optional<TransactionLogBloomCacher> transactionLogBloomCacher;
|
||||
private final Optional<EthScheduler> ethScheduler;
|
||||
private final ApiConfiguration apiConfig;
|
||||
|
||||
public BlockchainQueries(final Blockchain blockchain, final WorldStateArchive worldStateArchive) {
|
||||
this(blockchain, worldStateArchive, Optional.empty(), Optional.empty());
|
||||
}
|
||||
private final MiningParameters miningParameters;
|
||||
|
||||
public BlockchainQueries(
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final Blockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final EthScheduler scheduler) {
|
||||
this(blockchain, worldStateArchive, Optional.empty(), Optional.ofNullable(scheduler));
|
||||
}
|
||||
|
||||
public BlockchainQueries(
|
||||
final Blockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final Optional<Path> cachePath,
|
||||
final Optional<EthScheduler> scheduler) {
|
||||
final MiningParameters miningParameters) {
|
||||
this(
|
||||
protocolSchedule,
|
||||
blockchain,
|
||||
worldStateArchive,
|
||||
cachePath,
|
||||
scheduler,
|
||||
ImmutableApiConfiguration.builder().build());
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
miningParameters);
|
||||
}
|
||||
|
||||
public BlockchainQueries(
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final Blockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final EthScheduler scheduler,
|
||||
final MiningParameters miningParameters) {
|
||||
this(
|
||||
protocolSchedule,
|
||||
blockchain,
|
||||
worldStateArchive,
|
||||
Optional.empty(),
|
||||
Optional.ofNullable(scheduler),
|
||||
miningParameters);
|
||||
}
|
||||
|
||||
public BlockchainQueries(
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final Blockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final Optional<Path> cachePath,
|
||||
final Optional<EthScheduler> scheduler,
|
||||
final ApiConfiguration apiConfig) {
|
||||
final MiningParameters miningParameters) {
|
||||
this(
|
||||
protocolSchedule,
|
||||
blockchain,
|
||||
worldStateArchive,
|
||||
cachePath,
|
||||
scheduler,
|
||||
ImmutableApiConfiguration.builder().build(),
|
||||
miningParameters);
|
||||
}
|
||||
|
||||
public BlockchainQueries(
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final Blockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final Optional<Path> cachePath,
|
||||
final Optional<EthScheduler> scheduler,
|
||||
final ApiConfiguration apiConfig,
|
||||
final MiningParameters miningParameters) {
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.blockchain = blockchain;
|
||||
this.worldStateArchive = worldStateArchive;
|
||||
this.cachePath = cachePath;
|
||||
@@ -113,6 +144,7 @@ public class BlockchainQueries {
|
||||
new TransactionLogBloomCacher(blockchain, cachePath.get(), scheduler.get()))
|
||||
: Optional.empty();
|
||||
this.apiConfig = apiConfig;
|
||||
this.miningParameters = miningParameters;
|
||||
}
|
||||
|
||||
public Blockchain getBlockchain() {
|
||||
@@ -943,10 +975,15 @@ public class BlockchainQueries {
|
||||
return getAndMapWorldState(blockHash, mapper);
|
||||
}
|
||||
|
||||
public Optional<Long> gasPrice() {
|
||||
public Wei gasPrice() {
|
||||
final long blockHeight = headBlockNumber();
|
||||
final long[] gasCollection =
|
||||
LongStream.range(Math.max(0, blockHeight - apiConfig.getGasPriceBlocks()), blockHeight)
|
||||
final var chainHeadHeader = blockchain.getChainHeadHeader();
|
||||
final var nextBlockProtocolSpec =
|
||||
protocolSchedule.getForNextBlockHeader(chainHeadHeader, System.currentTimeMillis());
|
||||
final var nextBlockFeeMarket = nextBlockProtocolSpec.getFeeMarket();
|
||||
final Wei[] gasCollection =
|
||||
LongStream.rangeClosed(
|
||||
Math.max(0, blockHeight - apiConfig.getGasPriceBlocks() + 1), blockHeight)
|
||||
.mapToObj(
|
||||
l ->
|
||||
blockchain
|
||||
@@ -957,20 +994,46 @@ public class BlockchainQueries {
|
||||
() -> new IllegalStateException("Could not retrieve block #" + l)))
|
||||
.flatMap(Collection::stream)
|
||||
.filter(t -> t.getGasPrice().isPresent())
|
||||
.mapToLong(t -> t.getGasPrice().get().toLong())
|
||||
.map(t -> t.getGasPrice().get())
|
||||
.sorted()
|
||||
.toArray();
|
||||
.toArray(Wei[]::new);
|
||||
return (gasCollection == null || gasCollection.length == 0)
|
||||
? Optional.empty()
|
||||
: Optional.of(
|
||||
Math.max(
|
||||
apiConfig.getGasPriceMinSupplier().getAsLong(),
|
||||
Math.min(
|
||||
apiConfig.getGasPriceMax(),
|
||||
gasCollection[
|
||||
Math.min(
|
||||
gasCollection.length - 1,
|
||||
(int) ((gasCollection.length) * apiConfig.getGasPriceFraction()))])));
|
||||
? gasPriceLowerBound(chainHeadHeader, nextBlockFeeMarket)
|
||||
: UInt256s.max(
|
||||
gasPriceLowerBound(chainHeadHeader, nextBlockFeeMarket),
|
||||
UInt256s.min(
|
||||
apiConfig.getGasPriceMax(),
|
||||
gasCollection[
|
||||
Math.min(
|
||||
gasCollection.length - 1,
|
||||
(int) ((gasCollection.length) * apiConfig.getGasPriceFraction()))]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the min gas required for a tx to be mineable. On networks with gas price fee market it
|
||||
* is just the minGasPrice, while on networks with base fee market it is the max between the
|
||||
* minGasPrice and the baseFee for the next block.
|
||||
*
|
||||
* @return the min gas required for a tx to be mineable.
|
||||
*/
|
||||
public Wei gasPriceLowerBound() {
|
||||
final var chainHeadHeader = blockchain.getChainHeadHeader();
|
||||
final var nextBlockProtocolSpec =
|
||||
protocolSchedule.getForNextBlockHeader(chainHeadHeader, System.currentTimeMillis());
|
||||
final var nextBlockFeeMarket = nextBlockProtocolSpec.getFeeMarket();
|
||||
return gasPriceLowerBound(chainHeadHeader, nextBlockFeeMarket);
|
||||
}
|
||||
|
||||
private Wei gasPriceLowerBound(
|
||||
final BlockHeader chainHeadHeader, final FeeMarket nextBlockFeeMarket) {
|
||||
final var minGasPrice = miningParameters.getMinTransactionGasPrice();
|
||||
|
||||
if (nextBlockFeeMarket.implementsBaseFee()) {
|
||||
return UInt256s.max(
|
||||
getNextBlockBaseFee(chainHeadHeader, (BaseFeeMarket) nextBlockFeeMarket), minGasPrice);
|
||||
}
|
||||
|
||||
return minGasPrice;
|
||||
}
|
||||
|
||||
public Optional<Wei> gasPriorityFee() {
|
||||
@@ -1000,6 +1063,31 @@ public class BlockchainQueries {
|
||||
(int) ((gasCollection.length) * apiConfig.getGasPriceFraction()))]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and return the value of the base fee for the next block, if the network has a base
|
||||
* fee market, otherwise return empty.
|
||||
*
|
||||
* @return the optional base fee
|
||||
*/
|
||||
public Optional<Wei> getNextBlockBaseFee() {
|
||||
final var chainHeadHeader = blockchain.getChainHeadHeader();
|
||||
final var nextBlockProtocolSpec =
|
||||
protocolSchedule.getForNextBlockHeader(chainHeadHeader, System.currentTimeMillis());
|
||||
final var nextBlockFeeMarket = nextBlockProtocolSpec.getFeeMarket();
|
||||
return nextBlockFeeMarket.implementsBaseFee()
|
||||
? Optional.of(getNextBlockBaseFee(chainHeadHeader, (BaseFeeMarket) nextBlockFeeMarket))
|
||||
: Optional.empty();
|
||||
}
|
||||
|
||||
private Wei getNextBlockBaseFee(
|
||||
final BlockHeader chainHeadHeader, final BaseFeeMarket nextBlockFeeMarket) {
|
||||
return nextBlockFeeMarket.computeBaseFee(
|
||||
chainHeadHeader.getNumber() + 1,
|
||||
chainHeadHeader.getBaseFee().orElse(Wei.ZERO),
|
||||
chainHeadHeader.getGasUsed(),
|
||||
nextBlockFeeMarket.targetGasUsed(chainHeadHeader));
|
||||
}
|
||||
|
||||
private <T> Optional<T> fromAccount(
|
||||
final Address address,
|
||||
final Hash blockHash,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.graphql;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.datatypes.TransactionType;
|
||||
@@ -26,6 +27,7 @@ import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
|
||||
import org.hyperledger.besu.ethereum.core.DefaultSyncStatus;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.eth.EthProtocol;
|
||||
@@ -80,14 +82,13 @@ public abstract class AbstractEthGraphQLHttpServiceTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setupTest() throws Exception {
|
||||
final Synchronizer synchronizerMock = Mockito.mock(Synchronizer.class);
|
||||
final Synchronizer synchronizerMock = mock(Synchronizer.class);
|
||||
final SyncStatus status = new DefaultSyncStatus(1, 2, 3, Optional.of(4L), Optional.of(5L));
|
||||
when(synchronizerMock.getSyncStatus()).thenReturn(Optional.of(status));
|
||||
|
||||
final PoWMiningCoordinator miningCoordinatorMock = Mockito.mock(PoWMiningCoordinator.class);
|
||||
when(miningCoordinatorMock.getMinTransactionGasPrice()).thenReturn(Wei.of(16));
|
||||
final PoWMiningCoordinator miningCoordinatorMock = mock(PoWMiningCoordinator.class);
|
||||
|
||||
final TransactionPool transactionPoolMock = Mockito.mock(TransactionPool.class);
|
||||
final TransactionPool transactionPoolMock = mock(TransactionPool.class);
|
||||
|
||||
when(transactionPoolMock.addTransactionViaApi(ArgumentMatchers.any(Transaction.class)))
|
||||
.thenReturn(ValidationResult.valid());
|
||||
@@ -112,11 +113,13 @@ public abstract class AbstractEthGraphQLHttpServiceTest {
|
||||
blockchain, blockchainSetupUtil.getWorldArchive(), null, new BadBlockManager());
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
blockchainSetupUtil.getProtocolSchedule(),
|
||||
context.getBlockchain(),
|
||||
context.getWorldStateArchive(),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
ImmutableApiConfiguration.builder().gasPriceMinSupplier(() -> 0).build());
|
||||
ImmutableApiConfiguration.builder().build(),
|
||||
MiningParameters.newDefault().setMinTransactionGasPrice(Wei.ZERO));
|
||||
|
||||
final Set<Capability> supportedCapabilities = new HashSet<>();
|
||||
supportedCapabilities.add(EthProtocol.ETH62);
|
||||
@@ -147,7 +150,7 @@ public abstract class AbstractEthGraphQLHttpServiceTest {
|
||||
synchronizerMock,
|
||||
GraphQLContextType.GAS_CAP,
|
||||
0L),
|
||||
Mockito.mock(EthScheduler.class));
|
||||
mock(EthScheduler.class));
|
||||
service.start().join();
|
||||
|
||||
client = new OkHttpClient();
|
||||
|
||||
@@ -216,7 +216,7 @@ public class GraphQLHttpServiceTest {
|
||||
@Test
|
||||
public void query_get() throws Exception {
|
||||
final Wei price = Wei.of(16);
|
||||
Mockito.when(blockchainQueries.gasPrice()).thenReturn(Optional.of(price.toLong()));
|
||||
Mockito.when(blockchainQueries.gasPrice()).thenReturn(price);
|
||||
Mockito.when(miningCoordinatorMock.getMinTransactionGasPrice()).thenReturn(price);
|
||||
|
||||
try (final Response resp = client.newCall(buildGetRequest("?query={gasPrice}")).execute()) {
|
||||
|
||||
@@ -145,7 +145,10 @@ public abstract class AbstractJsonRpcHttpServiceTest {
|
||||
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
blockchainSetupUtil.getBlockchain(), blockchainSetupUtil.getWorldArchive());
|
||||
blockchainSetupUtil.getProtocolSchedule(),
|
||||
blockchainSetupUtil.getBlockchain(),
|
||||
blockchainSetupUtil.getWorldArchive(),
|
||||
miningParameters);
|
||||
final FilterIdGenerator filterIdGenerator = mock(FilterIdGenerator.class);
|
||||
final FilterRepository filterRepository = new FilterRepository();
|
||||
when(filterIdGenerator.nextId()).thenReturn("0x1");
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -30,38 +32,57 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.blockcreation.PoWMiningCoordinator;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Difficulty;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.CancunFeeMarket;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.LegacyFeeMarket;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.LondonFeeMarket;
|
||||
import org.hyperledger.besu.evm.log.LogsBloomFilter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.internal.verification.VerificationModeFactory;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class EthGasPriceTest {
|
||||
private static final String JSON_RPC_VERSION = "2.0";
|
||||
private static final String ETH_METHOD = "eth_gasPrice";
|
||||
private static final long DEFAULT_BLOCK_GAS_LIMIT = 100_000;
|
||||
private static final long DEFAULT_BLOCK_GAS_USED = 21_000;
|
||||
private static final Wei DEFAULT_MIN_GAS_PRICE = Wei.of(1_000);
|
||||
private static final Wei DEFAULT_BASE_FEE = Wei.of(100_000);
|
||||
|
||||
@Mock private PoWMiningCoordinator miningCoordinator;
|
||||
@Mock private ProtocolSchedule protocolSchedule;
|
||||
@Mock private Blockchain blockchain;
|
||||
private EthGasPrice method;
|
||||
private final String JSON_RPC_VERSION = "2.0";
|
||||
private final String ETH_METHOD = "eth_gasPrice";
|
||||
private MiningParameters miningParameters;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
ApiConfiguration apiConfig = createDefaultApiConfiguration();
|
||||
miningParameters =
|
||||
MiningParameters.newDefault().setMinTransactionGasPrice(DEFAULT_MIN_GAS_PRICE);
|
||||
method = createEthGasPriceMethod(apiConfig);
|
||||
}
|
||||
|
||||
@@ -73,41 +94,57 @@ public class EthGasPriceTest {
|
||||
@Test
|
||||
public void shouldReturnMinValueWhenNoTransactionsExist() {
|
||||
final JsonRpcRequestContext request = requestWithParams();
|
||||
final String expectedWei = "0x4d2";
|
||||
final String expectedWei = "0x4d2"; // minGasPrice > nextBlockBaseFee
|
||||
miningParameters.setMinTransactionGasPrice(Wei.fromHexString(expectedWei));
|
||||
final JsonRpcResponse expectedResponse =
|
||||
new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei);
|
||||
when(miningCoordinator.getMinTransactionGasPrice()).thenReturn(Wei.of(1234));
|
||||
|
||||
when(blockchain.getChainHeadBlockNumber()).thenReturn(1000L);
|
||||
when(blockchain.getBlockByNumber(anyLong()))
|
||||
.thenAnswer(invocation -> createEmptyBlock(invocation.getArgument(0, Long.class)));
|
||||
mockBaseFeeMarket();
|
||||
|
||||
mockBlockchain(1000, 0);
|
||||
|
||||
final JsonRpcResponse actualResponse = method.response(request);
|
||||
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
|
||||
|
||||
verify(miningCoordinator).getMinTransactionGasPrice();
|
||||
verifyNoMoreInteractions(miningCoordinator);
|
||||
|
||||
verify(blockchain).getChainHeadBlockNumber();
|
||||
verify(blockchain, VerificationModeFactory.times(100)).getBlockByNumber(anyLong());
|
||||
verifyNoMoreInteractions(blockchain);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnMedianWhenTransactionsExist() {
|
||||
public void shouldReturnBaseFeeAsMinValueOnGenesis() {
|
||||
final JsonRpcRequestContext request = requestWithParams();
|
||||
final String expectedWei = "0x389fd980"; // 950Wei, gas prices are 900-999 wei.
|
||||
final String expectedWei =
|
||||
DEFAULT_BASE_FEE.toShortHexString(); // nextBlockBaseFee > minGasPrice
|
||||
miningParameters.setMinTransactionGasPrice(Wei.fromHexString(expectedWei));
|
||||
final JsonRpcResponse expectedResponse =
|
||||
new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei);
|
||||
|
||||
when(blockchain.getChainHeadBlockNumber()).thenReturn(1000L);
|
||||
when(blockchain.getBlockByNumber(anyLong()))
|
||||
.thenAnswer(invocation -> createFakeBlock(invocation.getArgument(0, Long.class)));
|
||||
mockBaseFeeMarket();
|
||||
|
||||
mockBlockchain(0, 0);
|
||||
|
||||
final JsonRpcResponse actualResponse = method.response(request);
|
||||
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
|
||||
|
||||
verifyNoMoreInteractions(miningCoordinator);
|
||||
verify(blockchain).getChainHeadBlockNumber();
|
||||
verify(blockchain, VerificationModeFactory.times(1)).getBlockByNumber(anyLong());
|
||||
verifyNoMoreInteractions(blockchain);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnMedianWhenTransactionsExist() {
|
||||
final JsonRpcRequestContext request = requestWithParams();
|
||||
final String expectedWei = "0x911c70"; // 9.51 mwei, gas prices are 9.01-10 mwei.
|
||||
final JsonRpcResponse expectedResponse =
|
||||
new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei);
|
||||
|
||||
mockBaseFeeMarket();
|
||||
|
||||
mockBlockchain(1000L, 1);
|
||||
|
||||
final JsonRpcResponse actualResponse = method.response(request);
|
||||
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
|
||||
|
||||
verify(blockchain).getChainHeadBlockNumber();
|
||||
verify(blockchain, VerificationModeFactory.times(100)).getBlockByNumber(anyLong());
|
||||
@@ -117,21 +154,19 @@ public class EthGasPriceTest {
|
||||
@Test
|
||||
public void shortChainQueriesAllBlocks() {
|
||||
final JsonRpcRequestContext request = requestWithParams();
|
||||
final String expectedWei = "0x2625a00";
|
||||
final String expectedWei = "0x64190"; // 410 kwei
|
||||
final JsonRpcResponse expectedResponse =
|
||||
new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei);
|
||||
|
||||
when(blockchain.getChainHeadBlockNumber()).thenReturn(80L);
|
||||
when(blockchain.getBlockByNumber(anyLong()))
|
||||
.thenAnswer(invocation -> createFakeBlock(invocation.getArgument(0, Long.class)));
|
||||
mockBaseFeeMarket();
|
||||
|
||||
mockBlockchain(80L, 1);
|
||||
|
||||
final JsonRpcResponse actualResponse = method.response(request);
|
||||
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
|
||||
|
||||
verifyNoMoreInteractions(miningCoordinator);
|
||||
|
||||
verify(blockchain).getChainHeadBlockNumber();
|
||||
verify(blockchain, VerificationModeFactory.times(80)).getBlockByNumber(anyLong());
|
||||
verify(blockchain, VerificationModeFactory.times(81)).getBlockByNumber(anyLong());
|
||||
verifyNoMoreInteractions(blockchain);
|
||||
}
|
||||
|
||||
@@ -141,9 +176,9 @@ public class EthGasPriceTest {
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnLimitedPriceWhenLowerBoundIsPresent() {
|
||||
long gasPrice = 5000000;
|
||||
long lowerBoundGasPrice = gasPrice + 1;
|
||||
verifyGasPriceLimit(lowerBoundGasPrice, null, lowerBoundGasPrice);
|
||||
long expectedGasPrice = 31_841 * 2;
|
||||
long lowerBoundCoefficient = 200;
|
||||
verifyGasPriceLimit(lowerBoundCoefficient, null, expectedGasPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,9 +187,9 @@ public class EthGasPriceTest {
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnLimitedPriceWhenUpperBoundIsPresent() {
|
||||
long gasPrice = 5000000;
|
||||
long upperBoundGasPrice = gasPrice - 1;
|
||||
verifyGasPriceLimit(null, upperBoundGasPrice, upperBoundGasPrice);
|
||||
long expectedGasPrice = (long) (31_841 * 1.5);
|
||||
long upperBoundCoefficient = 150;
|
||||
verifyGasPriceLimit(null, upperBoundCoefficient, expectedGasPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,25 +198,83 @@ public class EthGasPriceTest {
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnActualGasPriceWhenWithinBoundRange() {
|
||||
long gasPrice = 5000000;
|
||||
long lowerBoundGasPrice = gasPrice - 1;
|
||||
long upperBoundGasPrice = gasPrice + 1;
|
||||
verifyGasPriceLimit(lowerBoundGasPrice, upperBoundGasPrice, gasPrice);
|
||||
long gasPrice = 60_000;
|
||||
long lowerBoundCoefficient = 120;
|
||||
long upperBoundCoefficient = 200;
|
||||
verifyGasPriceLimit(lowerBoundCoefficient, upperBoundCoefficient, gasPrice);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> ethGasPriceAtGenesis() {
|
||||
return Stream.of(
|
||||
// base fee > min gas price
|
||||
Arguments.of(
|
||||
DEFAULT_MIN_GAS_PRICE.divide(2),
|
||||
Optional.of(DEFAULT_MIN_GAS_PRICE),
|
||||
DEFAULT_MIN_GAS_PRICE.subtract(
|
||||
DEFAULT_MIN_GAS_PRICE
|
||||
.multiply(125)
|
||||
.divide(1000)) // expect base fee for the 1st block
|
||||
),
|
||||
// base fee < min gas price
|
||||
Arguments.of(
|
||||
DEFAULT_BASE_FEE.multiply(2),
|
||||
Optional.of(DEFAULT_BASE_FEE),
|
||||
DEFAULT_BASE_FEE.multiply(2)) // expect min gas price value
|
||||
,
|
||||
|
||||
// no base fee market
|
||||
Arguments.of(
|
||||
DEFAULT_MIN_GAS_PRICE,
|
||||
Optional.empty(),
|
||||
DEFAULT_MIN_GAS_PRICE // expect min gas price value
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("ethGasPriceAtGenesis")
|
||||
public void ethGasPriceAtGenesis(
|
||||
final Wei minGasPrice, final Optional<Wei> maybeGenesisBaseFee, final Wei expectedGasPrice) {
|
||||
miningParameters.setMinTransactionGasPrice(minGasPrice);
|
||||
|
||||
if (maybeGenesisBaseFee.isPresent()) {
|
||||
mockBaseFeeMarket();
|
||||
mockBlockchain(maybeGenesisBaseFee.get(), 0, 0);
|
||||
} else {
|
||||
mockGasPriceMarket();
|
||||
mockBlockchain(null, 0, 0);
|
||||
}
|
||||
|
||||
final JsonRpcRequestContext request = requestWithParams();
|
||||
final JsonRpcResponse expectedResponse =
|
||||
new JsonRpcSuccessResponse(
|
||||
request.getRequest().getId(), expectedGasPrice.toShortHexString());
|
||||
|
||||
final JsonRpcResponse actualResponse = method.response(request);
|
||||
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
|
||||
|
||||
verify(blockchain).getChainHeadBlockNumber();
|
||||
verify(blockchain, VerificationModeFactory.times(1)).getBlockByNumber(anyLong());
|
||||
verifyNoMoreInteractions(blockchain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to verify the gas price limit.
|
||||
*
|
||||
* @param lowerBound The lower bound of the gas price.
|
||||
* @param upperBound The upper bound of the gas price.
|
||||
* @param lowerBoundCoefficient The lower bound of the gas price.
|
||||
* @param upperBoundCoefficient The upper bound of the gas price.
|
||||
* @param expectedGasPrice The expected gas price.
|
||||
*/
|
||||
private void verifyGasPriceLimit(
|
||||
final Long lowerBound, final Long upperBound, final long expectedGasPrice) {
|
||||
when(miningCoordinator.getMinTransactionGasPrice()).thenReturn(Wei.of(100));
|
||||
final Long lowerBoundCoefficient,
|
||||
final Long upperBoundCoefficient,
|
||||
final long expectedGasPrice) {
|
||||
miningParameters.setMinTransactionGasPrice(Wei.of(100));
|
||||
|
||||
mockBaseFeeMarket();
|
||||
|
||||
var apiConfig =
|
||||
createApiConfiguration(Optional.ofNullable(lowerBound), Optional.ofNullable(upperBound));
|
||||
createApiConfiguration(
|
||||
Optional.ofNullable(lowerBoundCoefficient), Optional.ofNullable(upperBoundCoefficient));
|
||||
method = createEthGasPriceMethod(apiConfig);
|
||||
|
||||
final JsonRpcRequestContext request = requestWithParams();
|
||||
@@ -189,78 +282,108 @@ public class EthGasPriceTest {
|
||||
new JsonRpcSuccessResponse(
|
||||
request.getRequest().getId(), Wei.of(expectedGasPrice).toShortHexString());
|
||||
|
||||
when(blockchain.getChainHeadBlockNumber()).thenReturn(10L);
|
||||
when(blockchain.getBlockByNumber(anyLong()))
|
||||
.thenAnswer(invocation -> createFakeBlock(invocation.getArgument(0, Long.class)));
|
||||
final var chainHeadBlockNumber = 10L;
|
||||
mockBlockchain(chainHeadBlockNumber, 1);
|
||||
|
||||
final JsonRpcResponse actualResponse = method.response(request);
|
||||
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
|
||||
}
|
||||
|
||||
private Object createFakeBlock(final Long height) {
|
||||
return Optional.of(
|
||||
new Block(
|
||||
new BlockHeader(
|
||||
Hash.EMPTY,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
Address.ZERO,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
LogsBloomFilter.builder().build(),
|
||||
Difficulty.ONE,
|
||||
height,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
Bytes.EMPTY,
|
||||
Wei.ZERO,
|
||||
Hash.EMPTY,
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null),
|
||||
new BlockBody(
|
||||
List.of(
|
||||
new Transaction.Builder()
|
||||
.nonce(0)
|
||||
.gasPrice(Wei.of(height * 1000000L))
|
||||
.gasLimit(0)
|
||||
.value(Wei.ZERO)
|
||||
.build()),
|
||||
List.of())));
|
||||
private void mockBaseFeeMarket() {
|
||||
mockFeeMarket(new LondonFeeMarket(0));
|
||||
}
|
||||
|
||||
private Object createEmptyBlock(final Long height) {
|
||||
return Optional.of(
|
||||
new Block(
|
||||
new BlockHeader(
|
||||
Hash.EMPTY,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
Address.ZERO,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
LogsBloomFilter.builder().build(),
|
||||
Difficulty.ONE,
|
||||
height,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
Bytes.EMPTY,
|
||||
Wei.ZERO,
|
||||
Hash.EMPTY,
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null),
|
||||
new BlockBody(List.of(), List.of())));
|
||||
private void mockGasPriceMarket() {
|
||||
mockFeeMarket(new LegacyFeeMarket());
|
||||
}
|
||||
|
||||
private void mockFeeMarket(final FeeMarket feeMarket) {
|
||||
final var protocolSpec = mock(ProtocolSpec.class);
|
||||
when(protocolSpec.getFeeMarket()).thenReturn(feeMarket);
|
||||
when(protocolSchedule.getForNextBlockHeader(any(), anyLong())).thenReturn(protocolSpec);
|
||||
}
|
||||
|
||||
private void mockBlockchain(final long chainHeadBlockNumber, final int txsNum) {
|
||||
mockBlockchain(DEFAULT_BASE_FEE, chainHeadBlockNumber, txsNum);
|
||||
}
|
||||
|
||||
private void mockBlockchain(
|
||||
final Wei genesisBaseFee, final long chainHeadBlockNumber, final int txsNum) {
|
||||
final var blocksByNumber = new HashMap<Long, Block>();
|
||||
|
||||
final var genesisBlock = createFakeBlock(0, 0, genesisBaseFee);
|
||||
blocksByNumber.put(0L, genesisBlock);
|
||||
|
||||
final var baseFeeMarket = new CancunFeeMarket(0, Optional.empty());
|
||||
|
||||
var baseFee = genesisBaseFee;
|
||||
for (long i = 1; i <= chainHeadBlockNumber; i++) {
|
||||
final var parentHeader = blocksByNumber.get(i - 1).getHeader();
|
||||
baseFee =
|
||||
baseFeeMarket.computeBaseFee(
|
||||
i,
|
||||
parentHeader.getBaseFee().get(),
|
||||
parentHeader.getGasUsed(),
|
||||
parentHeader.getGasLimit());
|
||||
blocksByNumber.put(i, createFakeBlock(i, txsNum, baseFee));
|
||||
}
|
||||
|
||||
when(blockchain.getChainHeadBlockNumber()).thenReturn(chainHeadBlockNumber);
|
||||
when(blockchain.getBlockByNumber(anyLong()))
|
||||
.thenAnswer(
|
||||
invocation -> Optional.of(blocksByNumber.get(invocation.getArgument(0, Long.class))));
|
||||
|
||||
when(blockchain.getChainHeadHeader())
|
||||
.thenReturn(blocksByNumber.get(chainHeadBlockNumber).getHeader());
|
||||
}
|
||||
|
||||
private Block createFakeBlock(final long height, final int txsNum, final Wei baseFee) {
|
||||
return createFakeBlock(
|
||||
height, txsNum, baseFee, DEFAULT_BLOCK_GAS_LIMIT, DEFAULT_BLOCK_GAS_USED * txsNum);
|
||||
}
|
||||
|
||||
private Block createFakeBlock(
|
||||
final long height,
|
||||
final int txsNum,
|
||||
final Wei baseFee,
|
||||
final long gasLimit,
|
||||
final long gasUsed) {
|
||||
return new Block(
|
||||
new BlockHeader(
|
||||
Hash.EMPTY,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
Address.ZERO,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
Hash.EMPTY_TRIE_HASH,
|
||||
LogsBloomFilter.builder().build(),
|
||||
Difficulty.ONE,
|
||||
height,
|
||||
gasLimit,
|
||||
gasUsed,
|
||||
0,
|
||||
Bytes.EMPTY,
|
||||
baseFee,
|
||||
Hash.EMPTY,
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null),
|
||||
new BlockBody(
|
||||
IntStream.range(0, txsNum)
|
||||
.mapToObj(
|
||||
i ->
|
||||
new Transaction.Builder()
|
||||
.nonce(i)
|
||||
.gasPrice(Wei.of(height * 10_000L))
|
||||
.gasLimit(gasUsed)
|
||||
.value(Wei.ZERO)
|
||||
.build())
|
||||
.toList(),
|
||||
List.of()));
|
||||
}
|
||||
|
||||
private JsonRpcRequestContext requestWithParams(final Object... params) {
|
||||
@@ -272,16 +395,15 @@ public class EthGasPriceTest {
|
||||
}
|
||||
|
||||
private ApiConfiguration createApiConfiguration(
|
||||
final Optional<Long> lowerBound, final Optional<Long> upperBound) {
|
||||
ImmutableApiConfiguration.Builder builder =
|
||||
ImmutableApiConfiguration.builder().gasPriceMinSupplier(() -> 100);
|
||||
final Optional<Long> lowerBoundCoefficient, final Optional<Long> upperBoundCoefficient) {
|
||||
ImmutableApiConfiguration.Builder builder = ImmutableApiConfiguration.builder();
|
||||
|
||||
lowerBound.ifPresent(
|
||||
lowerBoundCoefficient.ifPresent(
|
||||
value ->
|
||||
builder
|
||||
.isGasAndPriorityFeeLimitingEnabled(true)
|
||||
.lowerBoundGasAndPriorityFeeCoefficient(value));
|
||||
upperBound.ifPresent(
|
||||
upperBoundCoefficient.ifPresent(
|
||||
value ->
|
||||
builder
|
||||
.isGasAndPriorityFeeLimitingEnabled(true)
|
||||
@@ -292,8 +414,14 @@ public class EthGasPriceTest {
|
||||
|
||||
private EthGasPrice createEthGasPriceMethod(final ApiConfiguration apiConfig) {
|
||||
return new EthGasPrice(
|
||||
new BlockchainQueries(blockchain, null, Optional.empty(), Optional.empty(), apiConfig),
|
||||
miningCoordinator,
|
||||
new BlockchainQueries(
|
||||
protocolSchedule,
|
||||
blockchain,
|
||||
null,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
apiConfig,
|
||||
miningParameters),
|
||||
apiConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,10 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
|
||||
import java.util.List;
|
||||
@@ -66,6 +68,7 @@ public class EthGetBlockByNumberTest {
|
||||
private EthGetBlockByNumber method;
|
||||
@Mock private Synchronizer synchronizer;
|
||||
@Mock private WorldStateArchive worldStateArchive;
|
||||
@Mock private ProtocolSchedule protocolSchedule;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
@@ -87,7 +90,10 @@ public class EthGetBlockByNumberTest {
|
||||
latestHeader.getStateRoot(), latestHeader.getHash()))
|
||||
.thenReturn(Boolean.TRUE);
|
||||
|
||||
blockchainQueries = spy(new BlockchainQueries(blockchain, worldStateArchive));
|
||||
blockchainQueries =
|
||||
spy(
|
||||
new BlockchainQueries(
|
||||
protocolSchedule, blockchain, worldStateArchive, MiningParameters.newDefault()));
|
||||
|
||||
method = new EthGetBlockByNumber(blockchainQueries, blockResult, synchronizer);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
@@ -82,7 +83,10 @@ public class EthGetBlockReceiptsTest {
|
||||
blockchain.appendBlock(block, receipts);
|
||||
}
|
||||
|
||||
blockchainQueries = spy(new BlockchainQueries(blockchain, worldStateArchive));
|
||||
blockchainQueries =
|
||||
spy(
|
||||
new BlockchainQueries(
|
||||
protocolSchedule, blockchain, worldStateArchive, MiningParameters.newDefault()));
|
||||
protocolSchedule = mock(ProtocolSchedule.class);
|
||||
method = new EthGetBlockReceipts(blockchainQueries, protocolSchedule);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.chain.ChainHead;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.proof.WorldStateProof;
|
||||
import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
@@ -63,6 +65,7 @@ import org.mockito.quality.Strictness;
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
class EthGetProofTest {
|
||||
@Mock private Blockchain blockchain;
|
||||
@Mock private ProtocolSchedule protocolSchedule;
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private WorldStateArchive archive;
|
||||
@@ -83,7 +86,10 @@ class EthGetProofTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
blockchainQueries = spy(new BlockchainQueries(blockchain, archive));
|
||||
blockchainQueries =
|
||||
spy(
|
||||
new BlockchainQueries(
|
||||
protocolSchedule, blockchain, archive, MiningParameters.newDefault()));
|
||||
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
|
||||
when(blockchainQueries.headBlockNumber()).thenReturn(14L);
|
||||
when(blockchain.getChainHead()).thenReturn(chainHead);
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.mainnet.PoWHasher;
|
||||
@@ -189,7 +190,12 @@ public class EthGetTransactionReceiptTest {
|
||||
private final Blockchain blockchain = mock(Blockchain.class);
|
||||
|
||||
private final BlockchainQueries blockchainQueries =
|
||||
spy(new BlockchainQueries(blockchain, mock(WorldStateArchive.class)));
|
||||
spy(
|
||||
new BlockchainQueries(
|
||||
protocolSchedule,
|
||||
blockchain,
|
||||
mock(WorldStateArchive.class),
|
||||
MiningParameters.newDefault()));
|
||||
private final EthGetTransactionReceipt ethGetTransactionReceipt =
|
||||
new EthGetTransactionReceipt(blockchainQueries, protocolSchedule);
|
||||
private final String receiptString =
|
||||
|
||||
@@ -32,8 +32,10 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
|
||||
import org.hyperledger.besu.ethereum.core.BlockDataGenerator.BlockOptions;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
|
||||
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
@@ -47,6 +49,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
@@ -73,9 +76,16 @@ public class NewBlockHeadersSubscriptionServiceTest {
|
||||
private final SubscriptionManager subscriptionManagerSpy =
|
||||
new SubscriptionManager(new NoOpMetricsSystem());
|
||||
|
||||
@Mock ProtocolSchedule protocolSchedule;
|
||||
|
||||
@Spy
|
||||
private final BlockchainQueries blockchainQueriesSpy =
|
||||
Mockito.spy(new BlockchainQueries(blockchain, createInMemoryWorldStateArchive()));
|
||||
Mockito.spy(
|
||||
new BlockchainQueries(
|
||||
protocolSchedule,
|
||||
blockchain,
|
||||
createInMemoryWorldStateArchive(),
|
||||
MiningParameters.newDefault()));
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
|
||||
@@ -28,8 +28,10 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Difficulty;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.evm.log.Log;
|
||||
import org.hyperledger.besu.evm.log.LogsBloomFilter;
|
||||
@@ -63,6 +65,7 @@ public class BlockchainQueriesLogCacheTest {
|
||||
private Hash testHash;
|
||||
private static LogsBloomFilter testLogsBloomFilter;
|
||||
|
||||
@Mock ProtocolSchedule protocolSchedule;
|
||||
@Mock MutableBlockchain blockchain;
|
||||
@Mock WorldStateArchive worldStateArchive;
|
||||
@Mock EthScheduler scheduler;
|
||||
@@ -127,7 +130,12 @@ public class BlockchainQueriesLogCacheTest {
|
||||
when(blockchain.getBlockBody(any())).thenReturn(Optional.of(fakeBody));
|
||||
blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
blockchain, worldStateArchive, Optional.of(cacheDir), Optional.of(scheduler));
|
||||
protocolSchedule,
|
||||
blockchain,
|
||||
worldStateArchive,
|
||||
Optional.of(cacheDir),
|
||||
Optional.of(scheduler),
|
||||
MiningParameters.newDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,9 +28,11 @@ import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
|
||||
import org.hyperledger.besu.ethereum.core.BlockDataGenerator.BlockOptions;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.LogWithMetadata;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldState;
|
||||
@@ -46,6 +48,7 @@ import java.util.stream.Collectors;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class BlockchainQueriesTest {
|
||||
private BlockDataGenerator gen;
|
||||
@@ -504,6 +507,9 @@ public class BlockchainQueriesTest {
|
||||
assertThat(retrievedOmmerBlockHeader).isEqualTo(ommerBlockHeader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getGasPriceLowerBound() {}
|
||||
|
||||
private void assertBlockMatchesResult(
|
||||
final Block targetBlock, final BlockWithMetadata<TransactionWithMetadata, Hash> result) {
|
||||
assertThat(result.getHeader()).isEqualTo(targetBlock.getHeader());
|
||||
@@ -587,17 +593,15 @@ public class BlockchainQueriesTest {
|
||||
this.blockchain = blockchain;
|
||||
this.blockData = blockData;
|
||||
this.worldStateArchive = worldStateArchive;
|
||||
this.blockchainQueries = new BlockchainQueries(blockchain, worldStateArchive, scheduler);
|
||||
this.blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
Mockito.mock(ProtocolSchedule.class),
|
||||
blockchain,
|
||||
worldStateArchive,
|
||||
scheduler,
|
||||
MiningParameters.newDefault());
|
||||
}
|
||||
}
|
||||
|
||||
private static class BlockData {
|
||||
final Block block;
|
||||
final List<TransactionReceipt> receipts;
|
||||
|
||||
private BlockData(final Block block, final List<TransactionReceipt> receipts) {
|
||||
this.block = block;
|
||||
this.receipts = receipts;
|
||||
}
|
||||
}
|
||||
private record BlockData(Block block, List<TransactionReceipt> receipts) {}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"request": "{ gasPrice maxPriorityFeePerGas }",
|
||||
"response": {
|
||||
"data": {
|
||||
"gasPrice": "0x1",
|
||||
"gasPrice": "0x2dbc88c1",
|
||||
"maxPriorityFeePerGas": "0x3b9aca00"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -181,7 +181,9 @@ public class RetestethContext {
|
||||
blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
||||
protocolContext = new ProtocolContext(blockchain, worldStateArchive, null, badBlockManager);
|
||||
|
||||
blockchainQueries = new BlockchainQueries(blockchain, worldStateArchive, ethScheduler);
|
||||
blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
protocolSchedule, blockchain, worldStateArchive, ethScheduler, miningParameters);
|
||||
|
||||
final String sealengine = JsonUtil.getString(genesisConfig, "sealengine", "");
|
||||
headerValidationMode =
|
||||
|
||||
Reference in New Issue
Block a user