Add `rpc-gas-cap` via transaction simulator (#6156)

* Add `rpc-gas-cap` to enable user to cap gasLimit of certain RPC methods
Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com>

---------

Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com>
pull/6194/head
Gabriel Fukushima 11 months ago committed by GitHub
parent 569ef931ff
commit a5d5af0d32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      CHANGELOG.md
  2. 17
      besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java
  3. 7
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  4. 2
      besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java
  5. 6
      besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java
  6. 3
      besu/src/test/java/org/hyperledger/besu/RunnerTest.java
  7. 14
      besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
  8. 2
      besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java
  9. 1
      besu/src/test/resources/everything_config.toml
  10. 2
      consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java
  11. 1
      ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java
  12. 3
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLContextType.java
  13. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/BlockAdapterBase.java
  14. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java
  15. 10
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/DebugJsonRpcMethods.java
  16. 14
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java
  17. 11
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java
  18. 17
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java
  19. 4
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/AbstractEthGraphQLHttpServiceTest.java
  20. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java
  21. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java
  22. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java
  23. 2
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java
  24. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java
  25. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java
  26. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java
  27. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java
  28. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java
  29. 17
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java
  30. 102
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java
  31. 3
      ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeSmartContractPermissioningControllerTest.java
  32. 3
      ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/TransactionSmartContractPermissioningControllerTest.java

@ -11,6 +11,8 @@
- Transactions that takes too long to evaluate, during block creation, are dropped from the txpool [#6163](https://github.com/hyperledger/besu/pull/6163) - Transactions that takes too long to evaluate, during block creation, are dropped from the txpool [#6163](https://github.com/hyperledger/besu/pull/6163)
- New option `tx-pool-min-gas-price` to set a lower bound when accepting txs to the pool [#6098](https://github.com/hyperledger/besu/pull/6098) - New option `tx-pool-min-gas-price` to set a lower bound when accepting txs to the pool [#6098](https://github.com/hyperledger/besu/pull/6098)
- Allow a transaction selection plugin to specify custom selection results [#6190](https://github.com/hyperledger/besu/pull/6190) - Allow a transaction selection plugin to specify custom selection results [#6190](https://github.com/hyperledger/besu/pull/6190)
- Add `rpc-gas-cap` to allow users to set gas limit to the RPC methods used to simulate transactions[#6156](https://github.com/hyperledger/besu/pull/6156)
## 23.10.2 ## 23.10.2

@ -192,6 +192,7 @@ public class RunnerBuilder {
private JsonRpcIpcConfiguration jsonRpcIpcConfiguration; private JsonRpcIpcConfiguration jsonRpcIpcConfiguration;
private boolean legacyForkIdEnabled; private boolean legacyForkIdEnabled;
private Optional<Long> rpcMaxLogsRange; private Optional<Long> rpcMaxLogsRange;
private Optional<Long> rpcGasCap;
private Optional<EnodeDnsConfiguration> enodeDnsConfiguration; private Optional<EnodeDnsConfiguration> enodeDnsConfiguration;
/** /**
@ -585,6 +586,16 @@ public class RunnerBuilder {
this.rpcMaxLogsRange = rpcMaxLogsRange > 0 ? Optional.of(rpcMaxLogsRange) : Optional.empty(); this.rpcMaxLogsRange = rpcMaxLogsRange > 0 ? Optional.of(rpcMaxLogsRange) : Optional.empty();
return this; return this;
} }
/**
* Add Rpc gasLimit cap .
*
* @param rpcGasCap the rpc gas limit cap for transaction simulation methods
* @return the runner builder
*/
public RunnerBuilder rpcGasCap(final Long rpcGasCap) {
this.rpcGasCap = rpcGasCap > 0 ? Optional.of(rpcGasCap) : Optional.empty();
return this;
}
/** /**
* Add enode DNS configuration * Add enode DNS configuration
@ -661,7 +672,7 @@ public class RunnerBuilder {
final TransactionSimulator transactionSimulator = final TransactionSimulator transactionSimulator =
new TransactionSimulator( new TransactionSimulator(
context.getBlockchain(), context.getWorldStateArchive(), protocolSchedule); context.getBlockchain(), context.getWorldStateArchive(), protocolSchedule, rpcGasCap);
final Bytes localNodeId = nodeKey.getPublicKey().getEncodedBytes(); final Bytes localNodeId = nodeKey.getPublicKey().getEncodedBytes();
final Optional<NodePermissioningController> nodePermissioningController = final Optional<NodePermissioningController> nodePermissioningController =
@ -910,6 +921,7 @@ public class RunnerBuilder {
graphQlContextMap.putIfAbsent(GraphQLContextType.SYNCHRONIZER, synchronizer); graphQlContextMap.putIfAbsent(GraphQLContextType.SYNCHRONIZER, synchronizer);
graphQlContextMap.putIfAbsent( graphQlContextMap.putIfAbsent(
GraphQLContextType.CHAIN_ID, protocolSchedule.getChainId().map(UInt256::valueOf)); GraphQLContextType.CHAIN_ID, protocolSchedule.getChainId().map(UInt256::valueOf));
graphQlContextMap.putIfAbsent(GraphQLContextType.GAS_CAP, rpcGasCap);
final GraphQL graphQL; final GraphQL graphQL;
try { try {
graphQL = GraphQLProvider.buildGraphQL(fetchers); graphQL = GraphQLProvider.buildGraphQL(fetchers);
@ -1240,7 +1252,8 @@ public class RunnerBuilder {
besuController.getProtocolManager().ethContext().getEthPeers(), besuController.getProtocolManager().ethContext().getEthPeers(),
consensusEngineServer, consensusEngineServer,
rpcMaxLogsRange, rpcMaxLogsRange,
enodeDnsConfiguration); enodeDnsConfiguration,
rpcGasCap);
methods.putAll(besuController.getAdditionalJsonRpcMethods(jsonRpcApis)); methods.putAll(besuController.getAdditionalJsonRpcMethods(jsonRpcApis));
final var pluginMethods = final var pluginMethods =

@ -1230,6 +1230,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
"Specifies the maximum number of blocks to retrieve logs from via RPC. Must be >=0. 0 specifies no limit (default: ${DEFAULT-VALUE})") "Specifies the maximum number of blocks to retrieve logs from via RPC. Must be >=0. 0 specifies no limit (default: ${DEFAULT-VALUE})")
private final Long rpcMaxLogsRange = 5000L; private final Long rpcMaxLogsRange = 5000L;
@CommandLine.Option(
names = {"--rpc-gas-cap"},
description =
"Specifies the gasLimit cap for transaction simulation RPC methods. Must be >=0. 0 specifies no limit (default: ${DEFAULT-VALUE})")
private final Long rpcGasCap = 0L;
@CommandLine.Option( @CommandLine.Option(
names = {"--cache-last-blocks"}, names = {"--cache-last-blocks"},
description = "Specifies the number of last blocks to cache (default: ${DEFAULT-VALUE})") description = "Specifies the number of last blocks to cache (default: ${DEFAULT-VALUE})")
@ -2948,6 +2954,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
.storageProvider(keyValueStorageProvider(keyValueStorageName)) .storageProvider(keyValueStorageProvider(keyValueStorageName))
.rpcEndpointService(rpcEndpointServiceImpl) .rpcEndpointService(rpcEndpointServiceImpl)
.rpcMaxLogsRange(rpcMaxLogsRange) .rpcMaxLogsRange(rpcMaxLogsRange)
.rpcGasCap(rpcGasCap)
.enodeDnsConfiguration(getEnodeDnsConfiguration()) .enodeDnsConfiguration(getEnodeDnsConfiguration())
.build(); .build();

@ -367,7 +367,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
blockchain, epochManager, bftBlockInterface().get(), validatorOverrides); blockchain, epochManager, bftBlockInterface().get(), validatorOverrides);
final TransactionSimulator transactionSimulator = final TransactionSimulator transactionSimulator =
new TransactionSimulator(blockchain, worldStateArchive, protocolSchedule); new TransactionSimulator(blockchain, worldStateArchive, protocolSchedule, Optional.empty());
transactionValidatorProvider = transactionValidatorProvider =
new TransactionValidatorProvider( new TransactionValidatorProvider(
blockchain, new ValidatorContractController(transactionSimulator), qbftForksSchedule); blockchain, new ValidatorContractController(transactionSimulator), qbftForksSchedule);

@ -167,6 +167,7 @@ public final class RunnerBuilderTest {
.dataDir(dataDir.getRoot()) .dataDir(dataDir.getRoot())
.storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS)) .storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS))
.rpcEndpointService(new RpcEndpointServiceImpl()) .rpcEndpointService(new RpcEndpointServiceImpl())
.rpcGasCap(50_000_000L)
.build(); .build();
runner.startEthereumMainLoop(); runner.startEthereumMainLoop();
@ -211,6 +212,7 @@ public final class RunnerBuilderTest {
.dataDir(dataDir.getRoot()) .dataDir(dataDir.getRoot())
.storageProvider(storageProvider) .storageProvider(storageProvider)
.rpcEndpointService(new RpcEndpointServiceImpl()) .rpcEndpointService(new RpcEndpointServiceImpl())
.rpcGasCap(50_000_000L)
.build(); .build();
runner.startEthereumMainLoop(); runner.startEthereumMainLoop();
@ -270,6 +272,7 @@ public final class RunnerBuilderTest {
.storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS)) .storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS))
.rpcEndpointService(new RpcEndpointServiceImpl()) .rpcEndpointService(new RpcEndpointServiceImpl())
.besuPluginContext(mock(BesuPluginContextImpl.class)) .besuPluginContext(mock(BesuPluginContextImpl.class))
.rpcGasCap(50_000_000L)
.build(); .build();
assertThat(runner.getJsonRpcPort()).isPresent(); assertThat(runner.getJsonRpcPort()).isPresent();
@ -312,6 +315,7 @@ public final class RunnerBuilderTest {
.storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS)) .storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS))
.rpcEndpointService(new RpcEndpointServiceImpl()) .rpcEndpointService(new RpcEndpointServiceImpl())
.besuPluginContext(mock(BesuPluginContextImpl.class)) .besuPluginContext(mock(BesuPluginContextImpl.class))
.rpcGasCap(50_000_000L)
.build(); .build();
assertThat(runner.getEngineJsonRpcPort()).isPresent(); assertThat(runner.getEngineJsonRpcPort()).isPresent();
@ -353,6 +357,7 @@ public final class RunnerBuilderTest {
.storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS)) .storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS))
.rpcEndpointService(new RpcEndpointServiceImpl()) .rpcEndpointService(new RpcEndpointServiceImpl())
.besuPluginContext(mock(BesuPluginContextImpl.class)) .besuPluginContext(mock(BesuPluginContextImpl.class))
.rpcGasCap(50_000_000L)
.build(); .build();
assertThat(runner.getEngineJsonRpcPort()).isPresent(); assertThat(runner.getEngineJsonRpcPort()).isPresent();
@ -396,6 +401,7 @@ public final class RunnerBuilderTest {
.rpcEndpointService(new RpcEndpointServiceImpl()) .rpcEndpointService(new RpcEndpointServiceImpl())
.besuPluginContext(mock(BesuPluginContextImpl.class)) .besuPluginContext(mock(BesuPluginContextImpl.class))
.networkingConfiguration(NetworkingConfiguration.create()) .networkingConfiguration(NetworkingConfiguration.create())
.rpcGasCap(50_000_000L)
.build(); .build();
assertThat(runner.getJsonRpcPort()).isPresent(); assertThat(runner.getJsonRpcPort()).isPresent();

@ -192,7 +192,8 @@ public final class RunnerTest {
.permissioningService(new PermissioningServiceImpl()) .permissioningService(new PermissioningServiceImpl())
.staticNodes(emptySet()) .staticNodes(emptySet())
.storageProvider(new InMemoryKeyValueStorageProvider()) .storageProvider(new InMemoryKeyValueStorageProvider())
.rpcEndpointService(new RpcEndpointServiceImpl()); .rpcEndpointService(new RpcEndpointServiceImpl())
.rpcGasCap(50_000_000L);
Runner runnerBehind = null; Runner runnerBehind = null;
final Runner runnerAhead = final Runner runnerAhead =

@ -1587,6 +1587,20 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
} }
@Test
public void rpcGasCapOptionMustBeUsed() {
final long rpcGasCap = 150L;
parseCommand("--rpc-gas-cap", Long.toString(rpcGasCap));
verify(mockRunnerBuilder).rpcGasCap(longArgumentCaptor.capture());
verify(mockRunnerBuilder).build();
assertThat(longArgumentCaptor.getValue()).isEqualTo(rpcGasCap);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
@Test @Test
public void p2pPeerUpperBound_without_p2pPeerLowerBound_shouldSetLowerBoundEqualToUpperBound() { public void p2pPeerUpperBound_without_p2pPeerLowerBound_shouldSetLowerBoundEqualToUpperBound() {

@ -197,7 +197,6 @@ public abstract class CommandTestAbstract {
@Captor protected ArgumentCaptor<String> stringArgumentCaptor; @Captor protected ArgumentCaptor<String> stringArgumentCaptor;
@Captor protected ArgumentCaptor<Integer> intArgumentCaptor; @Captor protected ArgumentCaptor<Integer> intArgumentCaptor;
@Captor protected ArgumentCaptor<Long> longArgumentCaptor; @Captor protected ArgumentCaptor<Long> longArgumentCaptor;
@Captor protected ArgumentCaptor<Float> floatCaptor;
@Captor protected ArgumentCaptor<EthNetworkConfig> ethNetworkConfigArgumentCaptor; @Captor protected ArgumentCaptor<EthNetworkConfig> ethNetworkConfigArgumentCaptor;
@Captor protected ArgumentCaptor<SynchronizerConfiguration> syncConfigurationCaptor; @Captor protected ArgumentCaptor<SynchronizerConfiguration> syncConfigurationCaptor;
@Captor protected ArgumentCaptor<JsonRpcConfiguration> jsonRpcConfigArgumentCaptor; @Captor protected ArgumentCaptor<JsonRpcConfiguration> jsonRpcConfigArgumentCaptor;
@ -315,6 +314,7 @@ public abstract class CommandTestAbstract {
when(mockRunnerBuilder.legacyForkId(anyBoolean())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.legacyForkId(anyBoolean())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.rpcMaxLogsRange(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.rpcMaxLogsRange(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.enodeDnsConfiguration(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.enodeDnsConfiguration(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.rpcGasCap(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.build()).thenReturn(mockRunner); when(mockRunnerBuilder.build()).thenReturn(mockRunner);
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance(); final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();

@ -89,6 +89,7 @@ rpc-http-max-request-content-length = 5242880
rpc-max-logs-range=100 rpc-max-logs-range=100
json-pretty-print-enabled=false json-pretty-print-enabled=false
cache-last-blocks=512 cache-last-blocks=512
rpc-gas-cap = 50000000
# PRIVACY TLS # PRIVACY TLS
privacy-tls-enabled=false privacy-tls-enabled=false

@ -414,7 +414,7 @@ public class TestContextBuilder {
final BftValidatorOverrides validatorOverrides = convertBftForks(qbftForks); final BftValidatorOverrides validatorOverrides = convertBftForks(qbftForks);
final TransactionSimulator transactionSimulator = final TransactionSimulator transactionSimulator =
new TransactionSimulator(blockChain, worldStateArchive, protocolSchedule); new TransactionSimulator(blockChain, worldStateArchive, protocolSchedule, Optional.empty());
final BlockValidatorProvider blockValidatorProvider = final BlockValidatorProvider blockValidatorProvider =
BlockValidatorProvider.forkingValidatorProvider( BlockValidatorProvider.forkingValidatorProvider(

@ -188,6 +188,7 @@ public class JsonRpcTestMethodsFactory {
ethPeers, ethPeers,
Vertx.vertx(new VertxOptions().setWorkerPoolSize(1)), Vertx.vertx(new VertxOptions().setWorkerPoolSize(1)),
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty()); Optional.empty());
} }
} }

@ -22,5 +22,6 @@ public enum GraphQLContextType {
MINING_COORDINATOR, MINING_COORDINATOR,
SYNCHRONIZER, SYNCHRONIZER,
IS_ALIVE_HANDLER, IS_ALIVE_HANDLER,
CHAIN_ID CHAIN_ID,
GAS_CAP
} }

@ -209,10 +209,10 @@ public class BlockAdapterBase extends AdapterBase {
final ProtocolSchedule protocolSchedule = final ProtocolSchedule protocolSchedule =
environment.getGraphQlContext().get(GraphQLContextType.PROTOCOL_SCHEDULE); environment.getGraphQlContext().get(GraphQLContextType.PROTOCOL_SCHEDULE);
final long bn = header.getNumber(); final long bn = header.getNumber();
final Optional<Long> gasCap = environment.getGraphQlContext().get(GraphQLContextType.GAS_CAP);
final TransactionSimulator transactionSimulator = final TransactionSimulator transactionSimulator =
new TransactionSimulator( new TransactionSimulator(
query.getBlockchain(), query.getWorldStateArchive(), protocolSchedule); query.getBlockchain(), query.getWorldStateArchive(), protocolSchedule, gasCap);
long gasParam = -1; long gasParam = -1;
Wei gasPriceParam = null; Wei gasPriceParam = null;

@ -92,10 +92,10 @@ public class PendingStateAdapter extends AdapterBase {
final BlockchainQueries query = getBlockchainQueries(environment); final BlockchainQueries query = getBlockchainQueries(environment);
final ProtocolSchedule protocolSchedule = final ProtocolSchedule protocolSchedule =
environment.getGraphQlContext().get(GraphQLContextType.PROTOCOL_SCHEDULE); environment.getGraphQlContext().get(GraphQLContextType.PROTOCOL_SCHEDULE);
final Optional<Long> gasCap = environment.getGraphQlContext().get(GraphQLContextType.GAS_CAP);
final TransactionSimulator transactionSimulator = final TransactionSimulator transactionSimulator =
new TransactionSimulator( new TransactionSimulator(
query.getBlockchain(), query.getWorldStateArchive(), protocolSchedule); query.getBlockchain(), query.getWorldStateArchive(), protocolSchedule, gasCap);
long gasParam = -1; long gasParam = -1;
Wei gasPriceParam = null; Wei gasPriceParam = null;

@ -51,6 +51,7 @@ import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Map; import java.util.Map;
import java.util.Optional;
public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods { public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
@ -64,6 +65,8 @@ public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
private final Synchronizer synchronizer; private final Synchronizer synchronizer;
private final Path dataDir; private final Path dataDir;
private final Optional<Long> gasCap;
DebugJsonRpcMethods( DebugJsonRpcMethods(
final BlockchainQueries blockchainQueries, final BlockchainQueries blockchainQueries,
final ProtocolContext protocolContext, final ProtocolContext protocolContext,
@ -71,7 +74,8 @@ public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
final ObservableMetricsSystem metricsSystem, final ObservableMetricsSystem metricsSystem,
final TransactionPool transactionPool, final TransactionPool transactionPool,
final Synchronizer synchronizer, final Synchronizer synchronizer,
final Path dataDir) { final Path dataDir,
final Optional<Long> gasCap) {
this.blockchainQueries = blockchainQueries; this.blockchainQueries = blockchainQueries;
this.protocolContext = protocolContext; this.protocolContext = protocolContext;
this.protocolSchedule = protocolSchedule; this.protocolSchedule = protocolSchedule;
@ -79,6 +83,7 @@ public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
this.transactionPool = transactionPool; this.transactionPool = transactionPool;
this.synchronizer = synchronizer; this.synchronizer = synchronizer;
this.dataDir = dataDir; this.dataDir = dataDir;
this.gasCap = gasCap;
} }
@Override @Override
@ -122,6 +127,7 @@ public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
new TransactionSimulator( new TransactionSimulator(
blockchainQueries.getBlockchain(), blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(), blockchainQueries.getWorldStateArchive(),
protocolSchedule))); protocolSchedule,
gasCap)));
} }
} }

@ -87,6 +87,7 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
private final MiningCoordinator miningCoordinator; private final MiningCoordinator miningCoordinator;
private final Set<Capability> supportedCapabilities; private final Set<Capability> supportedCapabilities;
private final Optional<Long> maxLogRange; private final Optional<Long> maxLogRange;
private final Optional<Long> gasCap;
public EthJsonRpcMethods( public EthJsonRpcMethods(
final BlockchainQueries blockchainQueries, final BlockchainQueries blockchainQueries,
@ -96,7 +97,8 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
final TransactionPool transactionPool, final TransactionPool transactionPool,
final MiningCoordinator miningCoordinator, final MiningCoordinator miningCoordinator,
final Set<Capability> supportedCapabilities, final Set<Capability> supportedCapabilities,
final Optional<Long> maxLogRange) { final Optional<Long> maxLogRange,
final Optional<Long> gasCap) {
this.blockchainQueries = blockchainQueries; this.blockchainQueries = blockchainQueries;
this.synchronizer = synchronizer; this.synchronizer = synchronizer;
this.protocolSchedule = protocolSchedule; this.protocolSchedule = protocolSchedule;
@ -105,6 +107,7 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
this.miningCoordinator = miningCoordinator; this.miningCoordinator = miningCoordinator;
this.supportedCapabilities = supportedCapabilities; this.supportedCapabilities = supportedCapabilities;
this.maxLogRange = maxLogRange; this.maxLogRange = maxLogRange;
this.gasCap = gasCap;
} }
@Override @Override
@ -128,7 +131,8 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
new TransactionSimulator( new TransactionSimulator(
blockchainQueries.getBlockchain(), blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(), blockchainQueries.getWorldStateArchive(),
protocolSchedule)), protocolSchedule,
gasCap)),
new EthFeeHistory(protocolSchedule, blockchainQueries.getBlockchain()), new EthFeeHistory(protocolSchedule, blockchainQueries.getBlockchain()),
new EthGetCode(blockchainQueries), new EthGetCode(blockchainQueries),
new EthGetLogs(blockchainQueries, maxLogRange), new EthGetLogs(blockchainQueries, maxLogRange),
@ -157,13 +161,15 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
new TransactionSimulator( new TransactionSimulator(
blockchainQueries.getBlockchain(), blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(), blockchainQueries.getWorldStateArchive(),
protocolSchedule)), protocolSchedule,
gasCap)),
new EthCreateAccessList( new EthCreateAccessList(
blockchainQueries, blockchainQueries,
new TransactionSimulator( new TransactionSimulator(
blockchainQueries.getBlockchain(), blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(), blockchainQueries.getWorldStateArchive(),
protocolSchedule)), protocolSchedule,
gasCap)),
new EthMining(miningCoordinator), new EthMining(miningCoordinator),
new EthCoinbase(miningCoordinator), new EthCoinbase(miningCoordinator),
new EthProtocolVersion(supportedCapabilities), new EthProtocolVersion(supportedCapabilities),

@ -80,7 +80,8 @@ public class JsonRpcMethodsFactory {
final EthPeers ethPeers, final EthPeers ethPeers,
final Vertx consensusEngineServer, final Vertx consensusEngineServer,
final Optional<Long> maxLogRange, final Optional<Long> maxLogRange,
final Optional<EnodeDnsConfiguration> enodeDnsConfiguration) { final Optional<EnodeDnsConfiguration> enodeDnsConfiguration,
final Optional<Long> gasCap) {
final Map<String, JsonRpcMethod> enabled = new HashMap<>(); final Map<String, JsonRpcMethod> enabled = new HashMap<>();
if (!rpcApis.isEmpty()) { if (!rpcApis.isEmpty()) {
final JsonRpcMethod modules = new RpcModules(rpcApis); final JsonRpcMethod modules = new RpcModules(rpcApis);
@ -104,7 +105,8 @@ public class JsonRpcMethodsFactory {
metricsSystem, metricsSystem,
transactionPool, transactionPool,
synchronizer, synchronizer,
dataDir), dataDir,
gasCap),
new EeaJsonRpcMethods( new EeaJsonRpcMethods(
blockchainQueries, protocolSchedule, transactionPool, privacyParameters), blockchainQueries, protocolSchedule, transactionPool, privacyParameters),
new ExecutionEngineJsonRpcMethods( new ExecutionEngineJsonRpcMethods(
@ -121,7 +123,8 @@ public class JsonRpcMethodsFactory {
transactionPool, transactionPool,
miningCoordinator, miningCoordinator,
supportedCapabilities, supportedCapabilities,
maxLogRange), maxLogRange,
gasCap),
new NetJsonRpcMethods( new NetJsonRpcMethods(
p2pNetwork, p2pNetwork,
networkId, networkId,
@ -139,7 +142,7 @@ public class JsonRpcMethodsFactory {
new PrivxJsonRpcMethods( new PrivxJsonRpcMethods(
blockchainQueries, protocolSchedule, transactionPool, privacyParameters), blockchainQueries, protocolSchedule, transactionPool, privacyParameters),
new Web3JsonRpcMethods(clientVersion), new Web3JsonRpcMethods(clientVersion),
new TraceJsonRpcMethods(blockchainQueries, protocolSchedule), new TraceJsonRpcMethods(blockchainQueries, protocolSchedule, gasCap),
new TxPoolJsonRpcMethods(transactionPool), new TxPoolJsonRpcMethods(transactionPool),
new PluginsJsonRpcMethods(namedPlugins)); new PluginsJsonRpcMethods(namedPlugins));

@ -31,16 +31,22 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator; import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
import java.util.Map; import java.util.Map;
import java.util.Optional;
public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods { public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods {
private final BlockchainQueries blockchainQueries; private final BlockchainQueries blockchainQueries;
private final ProtocolSchedule protocolSchedule; private final ProtocolSchedule protocolSchedule;
private final Optional<Long> gasCap;
TraceJsonRpcMethods( TraceJsonRpcMethods(
final BlockchainQueries blockchainQueries, final ProtocolSchedule protocolSchedule) { final BlockchainQueries blockchainQueries,
final ProtocolSchedule protocolSchedule,
final Optional<Long> gasCap) {
this.blockchainQueries = blockchainQueries; this.blockchainQueries = blockchainQueries;
this.protocolSchedule = protocolSchedule; this.protocolSchedule = protocolSchedule;
this.gasCap = gasCap;
} }
@Override @Override
@ -65,20 +71,23 @@ public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods {
new TransactionSimulator( new TransactionSimulator(
blockchainQueries.getBlockchain(), blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(), blockchainQueries.getWorldStateArchive(),
protocolSchedule)), protocolSchedule,
gasCap)),
new TraceCallMany( new TraceCallMany(
blockchainQueries, blockchainQueries,
protocolSchedule, protocolSchedule,
new TransactionSimulator( new TransactionSimulator(
blockchainQueries.getBlockchain(), blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(), blockchainQueries.getWorldStateArchive(),
protocolSchedule)), protocolSchedule,
gasCap)),
new TraceRawTransaction( new TraceRawTransaction(
protocolSchedule, protocolSchedule,
blockchainQueries, blockchainQueries,
new TransactionSimulator( new TransactionSimulator(
blockchainQueries.getBlockchain(), blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(), blockchainQueries.getWorldStateArchive(),
protocolSchedule))); protocolSchedule,
gasCap)));
} }
} }

@ -143,7 +143,9 @@ public abstract class AbstractEthGraphQLHttpServiceTest {
GraphQLContextType.MINING_COORDINATOR, GraphQLContextType.MINING_COORDINATOR,
miningCoordinatorMock, miningCoordinatorMock,
GraphQLContextType.SYNCHRONIZER, GraphQLContextType.SYNCHRONIZER,
synchronizerMock), synchronizerMock,
GraphQLContextType.GAS_CAP,
Optional.empty()),
Mockito.mock(EthScheduler.class)); Mockito.mock(EthScheduler.class));
service.start().join(); service.start().join();

@ -191,6 +191,7 @@ public abstract class AbstractJsonRpcHttpServiceTest {
mock(EthPeers.class), mock(EthPeers.class),
syncVertx, syncVertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty()); Optional.empty());
} }

@ -128,6 +128,7 @@ public class JsonRpcHttpServiceHostAllowlistTest {
mock(EthPeers.class), mock(EthPeers.class),
vertx, vertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty())); Optional.empty()));
service = createJsonRpcHttpService(); service = createJsonRpcHttpService();
service.start().join(); service.start().join();

@ -157,6 +157,7 @@ public class JsonRpcHttpServiceLoginTest {
mock(EthPeers.class), mock(EthPeers.class),
vertx, vertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty())); Optional.empty()));
service = createJsonRpcHttpService(); service = createJsonRpcHttpService();
jwtAuth = service.authenticationService.get().getJwtAuthProvider(); jwtAuth = service.authenticationService.get().getJwtAuthProvider();

@ -230,6 +230,7 @@ public class JsonRpcHttpServiceRpcApisTest {
mock(EthPeers.class), mock(EthPeers.class),
vertx, vertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty())); Optional.empty()));
final JsonRpcHttpService jsonRpcHttpService = final JsonRpcHttpService jsonRpcHttpService =
new JsonRpcHttpService( new JsonRpcHttpService(
@ -340,6 +341,7 @@ public class JsonRpcHttpServiceRpcApisTest {
mock(EthPeers.class), mock(EthPeers.class),
vertx, vertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty())); Optional.empty()));
final JsonRpcHttpService jsonRpcHttpService = final JsonRpcHttpService jsonRpcHttpService =
new JsonRpcHttpService( new JsonRpcHttpService(

@ -136,6 +136,7 @@ public class JsonRpcHttpServiceTestBase {
ethPeersMock, ethPeersMock,
vertx, vertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty())); Optional.empty()));
service = createJsonRpcHttpService(createLimitedJsonRpcConfig()); service = createJsonRpcHttpService(createLimitedJsonRpcConfig());
service.start().join(); service.start().join();

@ -141,6 +141,7 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
mock(EthPeers.class), mock(EthPeers.class),
vertx, vertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty())); Optional.empty()));
System.setProperty("javax.net.ssl.trustStore", CLIENT_AS_CA_CERT.getKeyStoreFile().toString()); System.setProperty("javax.net.ssl.trustStore", CLIENT_AS_CA_CERT.getKeyStoreFile().toString());

@ -130,6 +130,7 @@ class JsonRpcHttpServiceTlsMisconfigurationTest {
mock(EthPeers.class), mock(EthPeers.class),
vertx, vertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty())); Optional.empty()));
} }

@ -131,6 +131,7 @@ public class JsonRpcHttpServiceTlsTest {
mock(EthPeers.class), mock(EthPeers.class),
vertx, vertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty())); Optional.empty()));
service = createJsonRpcHttpService(createJsonRpcConfig()); service = createJsonRpcHttpService(createJsonRpcConfig());
service.start().join(); service.start().join();

@ -192,6 +192,7 @@ public class WebSocketServiceLoginTest {
mock(EthPeers.class), mock(EthPeers.class),
vertx, vertx,
Optional.empty(), Optional.empty(),
Optional.empty(),
Optional.empty())); Optional.empty()));
websocketMethods.putAll(rpcMethods); websocketMethods.putAll(rpcMethods);

@ -48,6 +48,8 @@ import javax.annotation.Nonnull;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/* /*
* Used to process transactions for eth_call and eth_estimateGas. * Used to process transactions for eth_call and eth_estimateGas.
@ -56,6 +58,7 @@ import org.apache.tuweni.bytes.Bytes;
* blockchain or to estimate the transaction gas cost. * blockchain or to estimate the transaction gas cost.
*/ */
public class TransactionSimulator { public class TransactionSimulator {
private static final Logger LOG = LoggerFactory.getLogger(TransactionSimulator.class);
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM = private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
Suppliers.memoize(SignatureAlgorithmFactory::getInstance); Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
@ -76,14 +79,17 @@ public class TransactionSimulator {
private final Blockchain blockchain; private final Blockchain blockchain;
private final WorldStateArchive worldStateArchive; private final WorldStateArchive worldStateArchive;
private final ProtocolSchedule protocolSchedule; private final ProtocolSchedule protocolSchedule;
private final Optional<Long> rpcGasCap;
public TransactionSimulator( public TransactionSimulator(
final Blockchain blockchain, final Blockchain blockchain,
final WorldStateArchive worldStateArchive, final WorldStateArchive worldStateArchive,
final ProtocolSchedule protocolSchedule) { final ProtocolSchedule protocolSchedule,
final Optional<Long> rpcGasCap) {
this.blockchain = blockchain; this.blockchain = blockchain;
this.worldStateArchive = worldStateArchive; this.worldStateArchive = worldStateArchive;
this.protocolSchedule = protocolSchedule; this.protocolSchedule = protocolSchedule;
this.rpcGasCap = rpcGasCap;
} }
public Optional<TransactionSimulatorResult> process( public Optional<TransactionSimulatorResult> process(
@ -207,10 +213,17 @@ public class TransactionSimulator {
final Account sender = updater.get(senderAddress); final Account sender = updater.get(senderAddress);
final long nonce = sender != null ? sender.getNonce() : 0L; final long nonce = sender != null ? sender.getNonce() : 0L;
final long gasLimit = long gasLimit =
callParams.getGasLimit() >= 0 callParams.getGasLimit() >= 0
? callParams.getGasLimit() ? callParams.getGasLimit()
: blockHeaderToProcess.getGasLimit(); : blockHeaderToProcess.getGasLimit();
if (rpcGasCap.isPresent()) {
final long gasCap = rpcGasCap.get();
if (gasCap < gasLimit) {
gasLimit = gasCap;
LOG.info("Capping gasLimit to " + gasCap);
}
}
final Wei value = callParams.getValue() != null ? callParams.getValue() : Wei.ZERO; final Wei value = callParams.getValue() != null ? callParams.getValue() : Wei.ZERO;
final Bytes payload = callParams.getPayload() != null ? callParams.getPayload() : Bytes.EMPTY; final Bytes payload = callParams.getPayload() != null ? callParams.getPayload() : Bytes.EMPTY;

@ -40,6 +40,7 @@ import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParam
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult.Status; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult.Status;
@ -75,8 +76,9 @@ public class TransactionSimulatorTest {
private static final Address DEFAULT_FROM = private static final Address DEFAULT_FROM =
Address.fromHexString("0x0000000000000000000000000000000000000000"); Address.fromHexString("0x0000000000000000000000000000000000000000");
private static final long GASCAP = 500L;
private TransactionSimulator transactionSimulator; private TransactionSimulator transactionSimulator;
private TransactionSimulator cappedTransactionSimulator;
@Mock private Blockchain blockchain; @Mock private Blockchain blockchain;
@Mock private WorldStateArchive worldStateArchive; @Mock private WorldStateArchive worldStateArchive;
@ -84,13 +86,15 @@ public class TransactionSimulatorTest {
@Mock private ProtocolSchedule protocolSchedule; @Mock private ProtocolSchedule protocolSchedule;
@Mock private ProtocolSpec protocolSpec; @Mock private ProtocolSpec protocolSpec;
@Mock private MainnetTransactionProcessor transactionProcessor; @Mock private MainnetTransactionProcessor transactionProcessor;
private final BlockHeaderTestFixture blockHeaderTestFixture = new BlockHeaderTestFixture(); private final BlockHeaderTestFixture blockHeaderTestFixture = new BlockHeaderTestFixture();
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
this.transactionSimulator = this.transactionSimulator =
new TransactionSimulator(blockchain, worldStateArchive, protocolSchedule); new TransactionSimulator(blockchain, worldStateArchive, protocolSchedule, Optional.empty());
this.cappedTransactionSimulator =
new TransactionSimulator(
blockchain, worldStateArchive, protocolSchedule, Optional.of(GASCAP));
} }
@Test @Test
@ -156,7 +160,6 @@ public class TransactionSimulatorTest {
.payload(callParameter.getPayload()) .payload(callParameter.getPayload())
.signature(FAKE_SIGNATURE) .signature(FAKE_SIGNATURE)
.build(); .build();
mockProcessorStatusForTransaction(expectedTransaction, Status.SUCCESSFUL); mockProcessorStatusForTransaction(expectedTransaction, Status.SUCCESSFUL);
transactionSimulator.process( transactionSimulator.process(
@ -260,7 +263,6 @@ public class TransactionSimulatorTest {
.payload(callParameter.getPayload()) .payload(callParameter.getPayload())
.signature(FAKE_SIGNATURE) .signature(FAKE_SIGNATURE)
.build(); .build();
mockProcessorStatusForTransaction(expectedTransaction, Status.SUCCESSFUL); mockProcessorStatusForTransaction(expectedTransaction, Status.SUCCESSFUL);
transactionSimulator.process( transactionSimulator.process(
@ -523,6 +525,82 @@ public class TransactionSimulatorTest {
verifyTransactionWasProcessed(expectedTransaction); verifyTransactionWasProcessed(expectedTransaction);
} }
@Test
public void shouldCapGasLimitWhenOriginalTransactionExceedsGasCap() {
final CallParameter callParameter =
eip1559TransactionCallParameter(Wei.ZERO, Wei.ZERO, GASCAP + 1);
final BlockHeader blockHeader = mockBlockHeader(Hash.ZERO, 1L, Wei.ONE);
mockBlockchainForBlockHeader(blockHeader);
mockWorldStateForAccount(blockHeader, callParameter.getFrom(), 1L);
final Transaction expectedTransaction =
Transaction.builder()
.type(TransactionType.EIP1559)
.chainId(BigInteger.ONE)
.nonce(1L)
.gasLimit(GASCAP)
.maxFeePerGas(callParameter.getMaxFeePerGas().orElseThrow())
.maxPriorityFeePerGas(callParameter.getMaxPriorityFeePerGas().orElseThrow())
.to(callParameter.getTo())
.sender(callParameter.getFrom())
.value(callParameter.getValue())
.payload(callParameter.getPayload())
.signature(FAKE_SIGNATURE)
.build();
mockProtocolSpecForProcessWithWorldUpdater();
// call process with original transaction
cappedTransactionSimulator.process(
callParameter,
TransactionValidationParams.transactionSimulator(),
OperationTracer.NO_TRACING,
1L);
// expect overwritten transaction to be processed
verifyTransactionWasProcessed(expectedTransaction);
}
@Test
public void shouldKeepOriginalGasLimitWhenCapIsHigherThanOriginalValue() {
// generate a transaction with a gas limit that is lower than the gas cap
final CallParameter callParameter =
eip1559TransactionCallParameter(Wei.ZERO, Wei.ZERO, GASCAP - 1);
final BlockHeader blockHeader = mockBlockHeader(Hash.ZERO, 1L, Wei.ONE);
mockBlockchainForBlockHeader(blockHeader);
mockWorldStateForAccount(blockHeader, callParameter.getFrom(), 1L);
mockProtocolSpecForProcessWithWorldUpdater();
final Transaction expectedTransaction =
Transaction.builder()
.type(TransactionType.EIP1559)
.chainId(BigInteger.ONE)
.nonce(1L)
.gasLimit(callParameter.getGasLimit())
.maxFeePerGas(callParameter.getMaxFeePerGas().orElseThrow())
.maxPriorityFeePerGas(callParameter.getMaxPriorityFeePerGas().orElseThrow())
.to(callParameter.getTo())
.sender(callParameter.getFrom())
.value(callParameter.getValue())
.payload(callParameter.getPayload())
.signature(FAKE_SIGNATURE)
.build();
// call process with original transaction
cappedTransactionSimulator.process(
callParameter,
TransactionValidationParams.transactionSimulator(),
OperationTracer.NO_TRACING,
1L);
// expect transaction with the original gas limit to be processed
verifyTransactionWasProcessed(expectedTransaction);
}
private void mockWorldStateForAccount( private void mockWorldStateForAccount(
final BlockHeader blockHeader, final Address address, final long nonce) { final BlockHeader blockHeader, final Address address, final long nonce) {
final Account account = mock(Account.class); final Account account = mock(Account.class);
@ -558,8 +636,7 @@ public class TransactionSimulatorTest {
.thenReturn(Optional.of(blockHeader)); .thenReturn(Optional.of(blockHeader));
} }
private void mockProcessorStatusForTransaction( private void mockProtocolSpecForProcessWithWorldUpdater() {
final Transaction transaction, final Status status) {
final BlockHeaderFunctions blockHeaderFunctions = mock(BlockHeaderFunctions.class); final BlockHeaderFunctions blockHeaderFunctions = mock(BlockHeaderFunctions.class);
when(protocolSchedule.getChainId()).thenReturn(Optional.of(BigInteger.ONE)); when(protocolSchedule.getChainId()).thenReturn(Optional.of(BigInteger.ONE));
when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec);
@ -567,7 +644,11 @@ public class TransactionSimulatorTest {
when(protocolSpec.getMiningBeneficiaryCalculator()).thenReturn(BlockHeader::getCoinbase); when(protocolSpec.getMiningBeneficiaryCalculator()).thenReturn(BlockHeader::getCoinbase);
when(protocolSpec.getBlockHeaderFunctions()).thenReturn(blockHeaderFunctions); when(protocolSpec.getBlockHeaderFunctions()).thenReturn(blockHeaderFunctions);
when(protocolSpec.getFeeMarket()).thenReturn(FeeMarket.london(0)); when(protocolSpec.getFeeMarket()).thenReturn(FeeMarket.london(0));
}
private void mockProcessorStatusForTransaction(
final Transaction transaction, final Status status) {
mockProtocolSpecForProcessWithWorldUpdater();
final TransactionProcessingResult result = mock(TransactionProcessingResult.class); final TransactionProcessingResult result = mock(TransactionProcessingResult.class);
switch (status) { switch (status) {
case SUCCESSFUL: case SUCCESSFUL:
@ -628,10 +709,15 @@ public class TransactionSimulatorTest {
private CallParameter eip1559TransactionCallParameter( private CallParameter eip1559TransactionCallParameter(
final Wei maxFeePerGas, final Wei maxPriorityFeePerGas) { final Wei maxFeePerGas, final Wei maxPriorityFeePerGas) {
return eip1559TransactionCallParameter(maxFeePerGas, maxPriorityFeePerGas, 0L);
}
private CallParameter eip1559TransactionCallParameter(
final Wei maxFeePerGas, final Wei maxPriorityFeePerGas, final long gasLimit) {
return new CallParameter( return new CallParameter(
Address.fromHexString("0x0"), Address.fromHexString("0x0"),
Address.fromHexString("0x0"), Address.fromHexString("0x0"),
0, gasLimit,
Wei.of(0), Wei.of(0),
Optional.of(maxFeePerGas), Optional.of(maxFeePerGas),
Optional.of(maxPriorityFeePerGas), Optional.of(maxPriorityFeePerGas),

@ -38,6 +38,7 @@ import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.metrics.Counter; import org.hyperledger.besu.plugin.services.metrics.Counter;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.io.Resources; import com.google.common.io.Resources;
@ -70,7 +71,7 @@ public class NodeSmartContractPermissioningControllerTest {
genesisState.writeStateTo(worldArchive.getMutable()); genesisState.writeStateTo(worldArchive.getMutable());
final TransactionSimulator ts = final TransactionSimulator ts =
new TransactionSimulator(blockchain, worldArchive, protocolSchedule); new TransactionSimulator(blockchain, worldArchive, protocolSchedule, Optional.empty());
final Address contractAddress = Address.fromHexString(contractAddressString); final Address contractAddress = Address.fromHexString(contractAddressString);
when(metricsSystem.createCounter( when(metricsSystem.createCounter(

@ -41,6 +41,7 @@ import org.hyperledger.besu.plugin.services.metrics.Counter;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Optional;
import com.google.common.io.Resources; import com.google.common.io.Resources;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
@ -71,7 +72,7 @@ public class TransactionSmartContractPermissioningControllerTest {
genesisState.writeStateTo(worldArchive.getMutable()); genesisState.writeStateTo(worldArchive.getMutable());
final TransactionSimulator ts = final TransactionSimulator ts =
new TransactionSimulator(blockchain, worldArchive, protocolSchedule); new TransactionSimulator(blockchain, worldArchive, protocolSchedule, Optional.empty());
final Address contractAddress = Address.fromHexString(contractAddressString); final Address contractAddress = Address.fromHexString(contractAddressString);
when(metricsSystem.createCounter( when(metricsSystem.createCounter(

Loading…
Cancel
Save