diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java index 90de0b0e952..0657ed52f58 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.tests.acceptance.dsl.node; import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.BOUNDED; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; @@ -377,8 +378,9 @@ TransactionSimulator provideTransactionSimulator( final WorldStateArchive worldStateArchive, final ProtocolSchedule protocolSchedule, final ApiConfiguration apiConfiguration) { - return new TransactionSimulator( - blockchain, worldStateArchive, protocolSchedule, apiConfiguration.getGasCap()); + return new TransactionSimulator.Builder(blockchain, worldStateArchive, protocolSchedule) + .rpcGasCap(apiConfiguration.getGasCap(), BOUNDED) + .build(); } @Provides diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index 96eef547fed..cf01b41128d 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -20,6 +20,7 @@ import static java.util.function.Predicate.not; import static org.hyperledger.besu.controller.BesuController.CACHE_PATH; import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.BOUNDED; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; @@ -699,11 +700,10 @@ public Runner build() { final Synchronizer synchronizer = besuController.getSynchronizer(); final TransactionSimulator transactionSimulator = - new TransactionSimulator( - context.getBlockchain(), - context.getWorldStateArchive(), - protocolSchedule, - apiConfiguration.getGasCap()); + new TransactionSimulator.Builder( + context.getBlockchain(), context.getWorldStateArchive(), protocolSchedule) + .rpcGasCap(apiConfiguration.getGasCap(), BOUNDED) + .build(); final Bytes localNodeId = nodeKey.getPublicKey().getEncodedBytes(); final Optional nodePermissioningController = diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index e93518cad43..ee2d2cec0ca 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -26,6 +26,7 @@ import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_ENGINE_JSON_RPC_PORT; import static org.hyperledger.besu.ethereum.api.jsonrpc.authentication.EngineAuthService.EPHEMERAL_JWT_FILE; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.BOUNDED; import static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER; import org.hyperledger.besu.BesuInfo; @@ -1434,11 +1435,12 @@ private void startPlugins(final Runner runner) { besuController.getProtocolContext(), besuController.getProtocolSchedule()); transactionSimulationServiceImpl.init( besuController.getProtocolContext().getBlockchain(), - new TransactionSimulator( - besuController.getProtocolContext().getBlockchain(), - besuController.getProtocolContext().getWorldStateArchive(), - besuController.getProtocolSchedule(), - apiConfiguration.getGasCap())); + new TransactionSimulator.Builder( + besuController.getProtocolContext().getBlockchain(), + besuController.getProtocolContext().getWorldStateArchive(), + besuController.getProtocolSchedule()) + .rpcGasCap(apiConfiguration.getGasCap(), BOUNDED) + .build()); rpcEndpointServiceImpl.init(runner.getInProcessRpcMethods()); besuPluginContext.addService( diff --git a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java index 60eac179965..3639832d22b 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -394,7 +394,7 @@ protected BftContext createConsensusContext( blockchain, epochManager, bftBlockInterface().get(), validatorOverrides); final TransactionSimulator transactionSimulator = - new TransactionSimulator(blockchain, worldStateArchive, protocolSchedule, 0L); + new TransactionSimulator.Builder(blockchain, worldStateArchive, protocolSchedule).build(); transactionValidatorProvider = new TransactionValidatorProvider( blockchain, new ValidatorContractController(transactionSimulator), qbftForksSchedule); diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java index d90d5a15277..459ebc21d71 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java @@ -445,7 +445,7 @@ private static ControllerAndState createControllerAndFinalState( final BftValidatorOverrides validatorOverrides = convertBftForks(qbftForks); final TransactionSimulator transactionSimulator = - new TransactionSimulator(blockChain, worldStateArchive, protocolSchedule, 0L); + new TransactionSimulator.Builder(blockChain, worldStateArchive, protocolSchedule).build(); final BlockValidatorProvider blockValidatorProvider = BlockValidatorProvider.forkingValidatorProvider( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/BlockAdapterBase.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/BlockAdapterBase.java index 6d5b696353a..11b9743a3a3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/BlockAdapterBase.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/BlockAdapterBase.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.BOUNDED; + import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.BlobGas; import org.hyperledger.besu.datatypes.Hash; @@ -334,8 +336,10 @@ private Optional executeCall(final DataFetchingEnvironment environme final long bn = header.getNumber(); final long gasCap = environment.getGraphQlContext().get(GraphQLContextType.GAS_CAP); final TransactionSimulator transactionSimulator = - new TransactionSimulator( - query.getBlockchain(), query.getWorldStateArchive(), protocolSchedule, gasCap); + new TransactionSimulator.Builder( + query.getBlockchain(), query.getWorldStateArchive(), protocolSchedule) + .rpcGasCap(gasCap, BOUNDED) + .build(); long gasParam = -1; Wei gasPriceParam = null; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java index 49f6bc890f9..c666c2ac9a4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.BOUNDED; + import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.graphql.GraphQLContextType; @@ -147,9 +149,10 @@ public Optional getCall(final DataFetchingEnvironment environment) { environment.getGraphQlContext().get(GraphQLContextType.PROTOCOL_SCHEDULE); final long gasCap = environment.getGraphQlContext().get(GraphQLContextType.GAS_CAP); final TransactionSimulator transactionSimulator = - new TransactionSimulator( - query.getBlockchain(), query.getWorldStateArchive(), protocolSchedule, gasCap); - + new TransactionSimulator.Builder( + query.getBlockchain(), query.getWorldStateArchive(), protocolSchedule) + .rpcGasCap(gasCap, BOUNDED) + .build(); long gasParam = -1; Wei gasPriceParam = null; Wei valueParam = null; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/DebugJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/DebugJsonRpcMethods.java index 90ae97c5c4f..d50298d4f75 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/DebugJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/DebugJsonRpcMethods.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.methods; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.BOUNDED; + import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; @@ -123,10 +125,11 @@ protected Map create() { new DebugTraceCall( blockchainQueries, protocolSchedule, - new TransactionSimulator( - blockchainQueries.getBlockchain(), - blockchainQueries.getWorldStateArchive(), - protocolSchedule, - apiConfiguration.getGasCap()))); + new TransactionSimulator.Builder( + blockchainQueries.getBlockchain(), + blockchainQueries.getWorldStateArchive(), + protocolSchedule) + .rpcGasCap(apiConfiguration.getGasCap(), BOUNDED) + .build())); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java index 5baa1106462..1904c5a69dc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java @@ -14,6 +14,9 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.methods; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.BOUNDED; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.UNBOUNDED; + import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; @@ -127,11 +130,12 @@ protected Map create() { new EthGetBlockTransactionCountByHash(blockchainQueries), new EthCall( blockchainQueries, - new TransactionSimulator( - blockchainQueries.getBlockchain(), - blockchainQueries.getWorldStateArchive(), - protocolSchedule, - apiConfiguration.getGasCap())), + new TransactionSimulator.Builder( + blockchainQueries.getBlockchain(), + blockchainQueries.getWorldStateArchive(), + protocolSchedule) + .rpcGasCap(apiConfiguration.getGasCap(), UNBOUNDED) + .build()), new EthFeeHistory( protocolSchedule, blockchainQueries.getBlockchain(), @@ -161,18 +165,20 @@ protected Map create() { new EthSendTransaction(), new EthEstimateGas( blockchainQueries, - new TransactionSimulator( - blockchainQueries.getBlockchain(), - blockchainQueries.getWorldStateArchive(), - protocolSchedule, - apiConfiguration.getGasCap())), + new TransactionSimulator.Builder( + blockchainQueries.getBlockchain(), + blockchainQueries.getWorldStateArchive(), + protocolSchedule) + .rpcGasCap(apiConfiguration.getGasCap(), BOUNDED) + .build()), new EthCreateAccessList( blockchainQueries, - new TransactionSimulator( - blockchainQueries.getBlockchain(), - blockchainQueries.getWorldStateArchive(), - protocolSchedule, - apiConfiguration.getGasCap())), + new TransactionSimulator.Builder( + blockchainQueries.getBlockchain(), + blockchainQueries.getWorldStateArchive(), + protocolSchedule) + .rpcGasCap(apiConfiguration.getGasCap(), BOUNDED) + .build()), new EthMining(miningCoordinator), new EthCoinbase(miningCoordinator), new EthProtocolVersion(supportedCapabilities), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java index 6a36bebfcd5..8b7f6829064 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.methods; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.BOUNDED; + import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; @@ -76,26 +78,29 @@ protected Map create() { new TraceCall( blockchainQueries, protocolSchedule, - new TransactionSimulator( - blockchainQueries.getBlockchain(), - blockchainQueries.getWorldStateArchive(), - protocolSchedule, - apiConfiguration.getGasCap())), + new TransactionSimulator.Builder( + blockchainQueries.getBlockchain(), + blockchainQueries.getWorldStateArchive(), + protocolSchedule) + .rpcGasCap(apiConfiguration.getGasCap(), BOUNDED) + .build()), new TraceCallMany( blockchainQueries, protocolSchedule, - new TransactionSimulator( - blockchainQueries.getBlockchain(), - blockchainQueries.getWorldStateArchive(), - protocolSchedule, - apiConfiguration.getGasCap())), + new TransactionSimulator.Builder( + blockchainQueries.getBlockchain(), + blockchainQueries.getWorldStateArchive(), + protocolSchedule) + .rpcGasCap(apiConfiguration.getGasCap(), BOUNDED) + .build()), new TraceRawTransaction( protocolSchedule, blockchainQueries, - new TransactionSimulator( - blockchainQueries.getBlockchain(), - blockchainQueries.getWorldStateArchive(), - protocolSchedule, - apiConfiguration.getGasCap()))); + new TransactionSimulator.Builder( + blockchainQueries.getBlockchain(), + blockchainQueries.getWorldStateArchive(), + protocolSchedule) + .rpcGasCap(apiConfiguration.getGasCap(), BOUNDED) + .build())); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java index 4b886984c9c..e832c38e066 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java @@ -79,17 +79,17 @@ public class TransactionSimulator { private final Blockchain blockchain; private final WorldStateArchive worldStateArchive; private final ProtocolSchedule protocolSchedule; - private final long rpcGasCap; + private final SimulationGasLimitCalculator simulationGasLimitCalculator; - public TransactionSimulator( + private TransactionSimulator( final Blockchain blockchain, final WorldStateArchive worldStateArchive, final ProtocolSchedule protocolSchedule, - final long rpcGasCap) { + final SimulationGasLimitCalculator simulationGasLimitCalculator) { this.blockchain = blockchain; this.worldStateArchive = worldStateArchive; this.protocolSchedule = protocolSchedule; - this.rpcGasCap = rpcGasCap; + this.simulationGasLimitCalculator = simulationGasLimitCalculator; } public Optional process( @@ -230,22 +230,9 @@ public Optional processWithWorldUpdater( final Account sender = updater.get(senderAddress); final long nonce = sender != null ? sender.getNonce() : 0L; - final long txGasLimit = - callParams.getGasLimit() >= 0 - ? callParams.getGasLimit() - : blockHeaderToProcess.getGasLimit(); - - final long simulationGasLimit; - if (rpcGasCap > 0) { - simulationGasLimit = Math.min(txGasLimit, rpcGasCap); - LOG.trace( - "Gas limit capped at {} for transaction simulation, tx gas limit is {} and provided RPC gas cap is {}", - simulationGasLimit, - txGasLimit, - rpcGasCap); - } else { - simulationGasLimit = txGasLimit; - } + final long simulationGasLimit = + simulationGasLimitCalculator.calculate( + callParams.getGasLimit(), blockHeaderToProcess.getGasLimit()); final Wei value = callParams.getValue() != null ? callParams.getValue() : Wei.ZERO; final Bytes payload = callParams.getPayload() != null ? callParams.getPayload() : Bytes.EMPTY; @@ -387,4 +374,87 @@ public Optional doesAddressExist( return Optional.of(worldState.get(address) != null); } + + @FunctionalInterface + public interface SimulationGasLimitCalculator { + long calculate(final long txGasLimit, final long blockGasLimit); + + static long bounded(final long txGasLimit, final long blockGasLimit, final long rpcGasCap) { + final long txGasCap = txGasLimit >= 0 ? txGasLimit : blockGasLimit; + + if (rpcGasCap > 0) { + final long simulationGasLimit = Math.min(txGasCap, rpcGasCap); + LOG.trace( + "Gas limit capped at {} for transaction simulation, tx gas limit={}, block gas limit={}, RPC gas cap={}", + simulationGasLimit, + txGasLimit, + blockGasLimit, + rpcGasCap); + return simulationGasLimit; + } + return txGasLimit; + } + + static long unbounded(final long txGasLimit, final long blockGasLimit, final long rpcGasCap) { + + if (rpcGasCap > 0) { + LOG.trace("Returning RPC gas cap {} for transaction simulation", rpcGasCap); + + return rpcGasCap; + } + + final long simulationGasLimit = txGasLimit >= 0 ? txGasLimit : blockGasLimit; + + LOG.trace( + "Gas limit capped at {} for transaction simulation, tx gas limit={}, block gas limit={}", + simulationGasLimit, + txGasLimit, + blockGasLimit); + return simulationGasLimit; + } + } + + public enum RpcGasCapMode { + BOUNDED, + UNBOUNDED + } + + public static final class Builder { + private final Blockchain blockchain; + private final WorldStateArchive worldStateArchive; + private final ProtocolSchedule protocolSchedule; + private long rpcGasCap = 0; + private RpcGasCapMode rpcGasCapMode = RpcGasCapMode.BOUNDED; + + public Builder( + final Blockchain blockchain, + final WorldStateArchive worldStateArchive, + final ProtocolSchedule protocolSchedule) { + this.blockchain = blockchain; + this.worldStateArchive = worldStateArchive; + this.protocolSchedule = protocolSchedule; + } + + public Builder rpcGasCap(final long rpcGasCap, final RpcGasCapMode mode) { + this.rpcGasCap = rpcGasCap; + this.rpcGasCapMode = mode; + return this; + } + + public TransactionSimulator build() { + final SimulationGasLimitCalculator simulationGasLimitCalculator; + if (rpcGasCap > 0 && rpcGasCapMode.equals(RpcGasCapMode.UNBOUNDED)) { + simulationGasLimitCalculator = + (txGasLimit, blockGasLimit) -> + SimulationGasLimitCalculator.unbounded(txGasLimit, blockGasLimit, rpcGasCap); + } else { + simulationGasLimitCalculator = + (txGasLimit, blockGasLimit) -> + SimulationGasLimitCalculator.bounded(txGasLimit, blockGasLimit, rpcGasCap); + } + + return new TransactionSimulator( + blockchain, worldStateArchive, protocolSchedule, simulationGasLimitCalculator); + } + } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java index 61b1e1d7c82..8469e8dbc0b 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.transaction; import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.transaction.TransactionSimulator.RpcGasCapMode.UNBOUNDED; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; @@ -94,9 +95,11 @@ public class TransactionSimulatorTest { @BeforeEach public void setUp() { this.transactionSimulator = - new TransactionSimulator(blockchain, worldStateArchive, protocolSchedule, 0); + new TransactionSimulator.Builder(blockchain, worldStateArchive, protocolSchedule).build(); this.cappedTransactionSimulator = - new TransactionSimulator(blockchain, worldStateArchive, protocolSchedule, GAS_CAP); + new TransactionSimulator.Builder(blockchain, worldStateArchive, protocolSchedule) + .rpcGasCap(GAS_CAP, UNBOUNDED) + .build(); } @Test @@ -566,7 +569,47 @@ public void shouldCapGasLimitWhenOriginalTransactionExceedsGasCap() { } @Test - public void rpcGasCapShouldNotOverrideExplicitTxGasLimit() { + public void shouldUseRpcGasCapWhenCapIsUnboundedAndHigherThanGasLimit() { + // generate a transaction with a gas limit that is lower than the gas cap, + // expect the gas cap to override parameter gas limit + final CallParameter callParameter = + eip1559TransactionCallParameter(Wei.ZERO, Wei.ZERO, GAS_CAP - 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) + .gasLimit(GAS_CAP) + .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); + } + + @Test + public void shouldUseTxGasLimitWhenRpcGasCapIsBounded() { // generate a transaction with a gas limit that is lower than the gas cap, // expect the gas cap to not override tx gas limit final CallParameter callParameter = @@ -595,7 +638,7 @@ public void rpcGasCapShouldNotOverrideExplicitTxGasLimit() { .build(); // call process with original transaction - cappedTransactionSimulator.process( + transactionSimulator.process( callParameter, TransactionValidationParams.transactionSimulator(), OperationTracer.NO_TRACING, diff --git a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeSmartContractPermissioningControllerTest.java b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeSmartContractPermissioningControllerTest.java index a9c97b1cc4e..d083118265c 100644 --- a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeSmartContractPermissioningControllerTest.java +++ b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeSmartContractPermissioningControllerTest.java @@ -70,7 +70,7 @@ private NodeSmartContractPermissioningController setupController( genesisState.writeStateTo(worldArchive.getMutable()); final TransactionSimulator ts = - new TransactionSimulator(blockchain, worldArchive, protocolSchedule, 0L); + new TransactionSimulator.Builder(blockchain, worldArchive, protocolSchedule).build(); final Address contractAddress = Address.fromHexString(contractAddressString); when(metricsSystem.createCounter( diff --git a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/TransactionSmartContractPermissioningControllerTest.java b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/TransactionSmartContractPermissioningControllerTest.java index 1fd4f58a4bd..da805609d53 100644 --- a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/TransactionSmartContractPermissioningControllerTest.java +++ b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/TransactionSmartContractPermissioningControllerTest.java @@ -69,7 +69,7 @@ private TransactionSmartContractPermissioningController setupController( genesisState.writeStateTo(worldArchive.getMutable()); final TransactionSimulator ts = - new TransactionSimulator(blockchain, worldArchive, protocolSchedule, 0L); + new TransactionSimulator.Builder(blockchain, worldArchive, protocolSchedule).build(); final Address contractAddress = Address.fromHexString(contractAddressString); when(metricsSystem.createCounter(