From 6169da46516edc58c4703e04a4d75b1ae2e48e9c Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Mon, 2 Dec 2024 15:13:19 +1100 Subject: [PATCH 1/9] Allow frontier simulation Signed-off-by: Gabriel-Trintinalia --- .../transaction/TransactionSimulator.java | 20 ++++++---- .../transaction/TransactionSimulatorTest.java | 37 +++++++++++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) 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 1c6140f1d1f..40a4fa2692b 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 @@ -318,7 +318,6 @@ public Optional processWithWorldUpdater( buildTransaction( callParams, transactionValidationParams, - header, senderAddress, nonce, simulationGasCap, @@ -400,7 +399,6 @@ private long calculateSimulationGasCap( private Optional buildTransaction( final CallParameter callParams, final TransactionValidationParams transactionValidationParams, - final BlockHeader header, final Address senderAddress, final long nonce, final long gasLimit, @@ -437,12 +435,20 @@ private Optional buildTransaction( maxPriorityFeePerGas = callParams.getMaxPriorityFeePerGas().orElse(gasPrice); maxFeePerBlobGas = callParams.getMaxFeePerBlobGas().orElse(blobGasPrice); } - if (header.getBaseFee().isEmpty()) { + + if (callParams.getMaxPriorityFeePerGas().isEmpty() + && callParams.getMaxFeePerGas().isEmpty()) { + // if maxPriorityFeePerGas and maxFeePerGas are not set, use gasPrice transactionBuilder.gasPrice(gasPrice); - } else if (protocolSchedule.getChainId().isPresent()) { - transactionBuilder.maxFeePerGas(maxFeePerGas).maxPriorityFeePerGas(maxPriorityFeePerGas); - } else { - return Optional.empty(); + } + + if (protocolSchedule.getChainId().isPresent()) { + // only set maxFeePerGas and maxPriorityFeePerGas if they are present, otherwise transaction will be considered + // EIP-1559 transaction even if the simulation is for a legacy transaction + if (callParams.getMaxPriorityFeePerGas().isPresent() + || callParams.getMaxFeePerGas().isPresent()) { + transactionBuilder.maxFeePerGas(maxFeePerGas).maxPriorityFeePerGas(maxPriorityFeePerGas); + } } transactionBuilder.guessType(); 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 e0715e58477..b8f349cca39 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 @@ -912,4 +912,41 @@ private CallParameter blobTransactionCallParameter( Optional.of(maxFeePerBlobGas), Optional.of(bwc.getVersionedHashes())); } + + @Test + public void shouldSimulateLegacyTransactionWhenBaseFeeNotZero() { + // tests that the transaction simulator will simulate a legacy transaction when the base fee is not zero + // and the transaction is a legacy transaction + + final CallParameter callParameter = legacyTransactionCallParameter(); + + final BlockHeader blockHeader = + blockHeaderTestFixture + .number(1L).stateRoot(Hash.ZERO) + .baseFeePerGas(Wei.of(7)) + .buildHeader(); + + mockBlockchainForBlockHeader(blockHeader); + mockWorldStateForAccount(blockHeader, callParameter.getFrom(), 1L); + + final Transaction expectedTransaction = + Transaction.builder() + .type(TransactionType.FRONTIER) + .nonce(1L) + .gasPrice(callParameter.getGasPrice()) + .gasLimit(blockHeader.getGasLimit()) + .to(callParameter.getTo()) + .sender(callParameter.getFrom()) + .value(callParameter.getValue()) + .payload(callParameter.getPayload()) + .signature(FAKE_SIGNATURE) + .build(); + mockProcessorStatusForTransaction(expectedTransaction, Status.SUCCESSFUL); + + final Optional result = + transactionSimulator.process(callParameter, 1L); + + verifyTransactionWasProcessed(expectedTransaction); + assertThat(result.get().isSuccessful()).isTrue(); + } } From f7fa14321cb95294509d91ba9690e5fc07b93a30 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Mon, 2 Dec 2024 15:16:17 +1100 Subject: [PATCH 2/9] fix spotless Signed-off-by: Gabriel-Trintinalia --- .../transaction/TransactionSimulator.java | 8 ++--- .../transaction/TransactionSimulatorTest.java | 36 ++++++++++--------- 2 files changed, 23 insertions(+), 21 deletions(-) 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 40a4fa2692b..c6a513b8566 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 @@ -436,17 +436,17 @@ private Optional buildTransaction( maxFeePerBlobGas = callParams.getMaxFeePerBlobGas().orElse(blobGasPrice); } - if (callParams.getMaxPriorityFeePerGas().isEmpty() - && callParams.getMaxFeePerGas().isEmpty()) { + if (callParams.getMaxPriorityFeePerGas().isEmpty() && callParams.getMaxFeePerGas().isEmpty()) { // if maxPriorityFeePerGas and maxFeePerGas are not set, use gasPrice transactionBuilder.gasPrice(gasPrice); } if (protocolSchedule.getChainId().isPresent()) { - // only set maxFeePerGas and maxPriorityFeePerGas if they are present, otherwise transaction will be considered + // only set maxFeePerGas and maxPriorityFeePerGas if they are present, otherwise transaction + // will be considered // EIP-1559 transaction even if the simulation is for a legacy transaction if (callParams.getMaxPriorityFeePerGas().isPresent() - || callParams.getMaxFeePerGas().isPresent()) { + || callParams.getMaxFeePerGas().isPresent()) { transactionBuilder.maxFeePerGas(maxFeePerGas).maxPriorityFeePerGas(maxPriorityFeePerGas); } } 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 b8f349cca39..8406d1e4c31 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 @@ -915,36 +915,38 @@ private CallParameter blobTransactionCallParameter( @Test public void shouldSimulateLegacyTransactionWhenBaseFeeNotZero() { - // tests that the transaction simulator will simulate a legacy transaction when the base fee is not zero + // tests that the transaction simulator will simulate a legacy transaction when the base fee is + // not zero // and the transaction is a legacy transaction final CallParameter callParameter = legacyTransactionCallParameter(); final BlockHeader blockHeader = - blockHeaderTestFixture - .number(1L).stateRoot(Hash.ZERO) - .baseFeePerGas(Wei.of(7)) - .buildHeader(); + blockHeaderTestFixture + .number(1L) + .stateRoot(Hash.ZERO) + .baseFeePerGas(Wei.of(7)) + .buildHeader(); mockBlockchainForBlockHeader(blockHeader); mockWorldStateForAccount(blockHeader, callParameter.getFrom(), 1L); final Transaction expectedTransaction = - Transaction.builder() - .type(TransactionType.FRONTIER) - .nonce(1L) - .gasPrice(callParameter.getGasPrice()) - .gasLimit(blockHeader.getGasLimit()) - .to(callParameter.getTo()) - .sender(callParameter.getFrom()) - .value(callParameter.getValue()) - .payload(callParameter.getPayload()) - .signature(FAKE_SIGNATURE) - .build(); + Transaction.builder() + .type(TransactionType.FRONTIER) + .nonce(1L) + .gasPrice(callParameter.getGasPrice()) + .gasLimit(blockHeader.getGasLimit()) + .to(callParameter.getTo()) + .sender(callParameter.getFrom()) + .value(callParameter.getValue()) + .payload(callParameter.getPayload()) + .signature(FAKE_SIGNATURE) + .build(); mockProcessorStatusForTransaction(expectedTransaction, Status.SUCCESSFUL); final Optional result = - transactionSimulator.process(callParameter, 1L); + transactionSimulator.process(callParameter, 1L); verifyTransactionWasProcessed(expectedTransaction); assertThat(result.get().isSuccessful()).isTrue(); From 796853d8a1b31db2fb7815f5013249abc8fa03db Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Mon, 2 Dec 2024 16:46:32 +1100 Subject: [PATCH 3/9] Fix unit tests Signed-off-by: Gabriel-Trintinalia --- .../transaction/TransactionSimulator.java | 57 ++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) 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 c6a513b8566..3af3e290ca2 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 @@ -296,9 +296,6 @@ public Optional processWithWorldUpdater( final long simulationGasCap = calculateSimulationGasCap(callParams.getGasLimit(), blockHeaderToProcess.getGasLimit()); - final Wei value = callParams.getValue() != null ? callParams.getValue() : Wei.ZERO; - final Bytes payload = callParams.getPayload() != null ? callParams.getPayload() : Bytes.EMPTY; - final MainnetTransactionProcessor transactionProcessor = protocolSchedule.getByBlockHeader(blockHeaderToProcess).getTransactionProcessor(); @@ -321,8 +318,6 @@ public Optional processWithWorldUpdater( senderAddress, nonce, simulationGasCap, - value, - payload, blobGasPrice); if (maybeTransaction.isEmpty()) { return Optional.empty(); @@ -402,9 +397,11 @@ private Optional buildTransaction( final Address senderAddress, final long nonce, final long gasLimit, - final Wei value, - final Bytes payload, final Wei blobGasPrice) { + + final Wei value = callParams.getValue() != null ? callParams.getValue() : Wei.ZERO; + final Bytes payload = callParams.getPayload() != null ? callParams.getPayload() : Bytes.EMPTY; + final Transaction.Builder transactionBuilder = Transaction.builder() .nonce(nonce) @@ -436,25 +433,20 @@ private Optional buildTransaction( maxFeePerBlobGas = callParams.getMaxFeePerBlobGas().orElse(blobGasPrice); } - if (callParams.getMaxPriorityFeePerGas().isEmpty() && callParams.getMaxFeePerGas().isEmpty()) { - // if maxPriorityFeePerGas and maxFeePerGas are not set, use gasPrice + if (shouldSeGasPrice(callParams)) { transactionBuilder.gasPrice(gasPrice); } - if (protocolSchedule.getChainId().isPresent()) { - // only set maxFeePerGas and maxPriorityFeePerGas if they are present, otherwise transaction - // will be considered - // EIP-1559 transaction even if the simulation is for a legacy transaction - if (callParams.getMaxPriorityFeePerGas().isPresent() - || callParams.getMaxFeePerGas().isPresent()) { - transactionBuilder.maxFeePerGas(maxFeePerGas).maxPriorityFeePerGas(maxPriorityFeePerGas); - } + if (shouldSetMaxFeePerGas(callParams)) { + transactionBuilder.maxFeePerGas(maxFeePerGas).maxPriorityFeePerGas(maxPriorityFeePerGas); } - transactionBuilder.guessType(); - if (transactionBuilder.getTransactionType().supportsBlob()) { + if (shouldSetBlobGasPrice(callParams)) { transactionBuilder.maxFeePerBlobGas(maxFeePerBlobGas); } + + transactionBuilder.guessType(); + if (transactionBuilder.getTransactionType().requiresChainId()) { callParams .getChainId() @@ -495,4 +487,31 @@ public Optional doesAddressExist( return Optional.of(worldState.get(address) != null); } + + private boolean shouldSeGasPrice(final CallParameter callParams) { + // if maxPriorityFeePerGas and maxFeePerGas are not set, use gasPrice + return callParams.getMaxPriorityFeePerGas().isEmpty() && callParams.getMaxFeePerGas().isEmpty(); + } + + private boolean shouldSetMaxFeePerGas(final CallParameter callParams) { + if (protocolSchedule.getChainId().isEmpty()) { + return false; + } + + if (shouldSetBlobGasPrice(callParams)) { + return true; + } + + // only set maxFeePerGas and maxPriorityFeePerGas if they are present, otherwise transaction + // will be considered EIP-1559 transaction even if the simulation is for a legacy transaction + return callParams.getMaxPriorityFeePerGas().isPresent() + || callParams.getMaxFeePerGas().isPresent(); + } + + private boolean shouldSetBlobGasPrice(final CallParameter callParams) { + if (protocolSchedule.getChainId().isEmpty()) { + return false; + } + return callParams.getBlobVersionedHashes().isPresent(); + } } From 78ae9c1fbb480f17d41c913e1a05cadd19065a00 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Tue, 3 Dec 2024 13:18:58 +1100 Subject: [PATCH 4/9] Fix unit tests Signed-off-by: Gabriel-Trintinalia --- .../london/EthEstimateGasIntegrationTest.java | 1 + .../internal/parameters/JsonCallParameter.java | 11 ++++++++--- .../jsonrpc/internal/methods/EthCallTest.java | 2 +- .../transaction/TransactionSimulator.java | 18 ++++++++++++++---- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java index 5fde9ccecbd..7c8cb8a08d7 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java @@ -137,6 +137,7 @@ public void shouldReturnErrorWithInvalidChainId() { .withChainId(BLOCKCHAIN.getChainId().add(BigInteger.ONE)) .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) .withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1")) + .withMaxFeePerGas(Wei.ONE) .withValue(Wei.ONE) .build(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java index 85dabda5719..9c7f858b4a3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java @@ -123,7 +123,7 @@ public static final class JsonCallParameterBuilder { private Optional chainId = Optional.empty(); private Address from; private Address to; - private long gas = -1; + private Optional gas = Optional.empty(); private Optional maxPriorityFeePerGas = Optional.empty(); private Optional maxFeePerGas = Optional.empty(); private Optional maxFeePerBlobGas = Optional.empty(); @@ -198,7 +198,7 @@ public JsonCallParameterBuilder withTo(final Address to) { */ @JsonDeserialize(using = GasDeserializer.class) public JsonCallParameterBuilder withGas(final Long gas) { - this.gas = Optional.ofNullable(gas).orElse(-1L); + this.gas = Optional.ofNullable(gas); return this; } @@ -361,13 +361,18 @@ public JsonCallParameter build() { throw new IllegalArgumentException("Only one of 'input' or 'data' should be provided"); } + if (gas.isPresent() && (maxFeePerBlobGas.isPresent() || maxPriorityFeePerGas.isPresent())) { + throw new IllegalArgumentException( + "both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified"); + } + final Bytes payload = input != null ? input : data; return new JsonCallParameter( chainId, from, to, - gas, + gas.orElse(-1L), gasPrice, maxPriorityFeePerGas, maxFeePerGas, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java index 7de6f65aae2..d06541a9d60 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java @@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; 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.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.chain.Blockchain; @@ -478,7 +479,6 @@ private JsonCallParameter callParameter( return new JsonCallParameter.JsonCallParameterBuilder() .withFrom(Address.fromHexString("0x0")) .withTo(Address.fromHexString("0x0")) - .withGas(0L) .withGasPrice(gasPrice) .withMaxFeePerGas(maxFeesPerGas) .withMaxPriorityFeePerGas(maxPriorityFeesPerGas) 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 3af3e290ca2..e4db6aafb15 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 @@ -315,6 +315,7 @@ public Optional processWithWorldUpdater( buildTransaction( callParams, transactionValidationParams, + header, senderAddress, nonce, simulationGasCap, @@ -394,6 +395,7 @@ private long calculateSimulationGasCap( private Optional buildTransaction( final CallParameter callParams, final TransactionValidationParams transactionValidationParams, + final BlockHeader header, final Address senderAddress, final long nonce, final long gasLimit, @@ -433,11 +435,11 @@ private Optional buildTransaction( maxFeePerBlobGas = callParams.getMaxFeePerBlobGas().orElse(blobGasPrice); } - if (shouldSeGasPrice(callParams)) { + if (shouldSetGasPrice(callParams, header)) { transactionBuilder.gasPrice(gasPrice); } - if (shouldSetMaxFeePerGas(callParams)) { + if (shouldSetMaxFeePerGas(callParams, header)) { transactionBuilder.maxFeePerGas(maxFeePerGas).maxPriorityFeePerGas(maxPriorityFeePerGas); } @@ -488,16 +490,24 @@ public Optional doesAddressExist( return Optional.of(worldState.get(address) != null); } - private boolean shouldSeGasPrice(final CallParameter callParams) { + private boolean shouldSetGasPrice(final CallParameter callParams, final BlockHeader header) { + if (header.getBaseFee().isEmpty()) { + return true; + } + // if maxPriorityFeePerGas and maxFeePerGas are not set, use gasPrice return callParams.getMaxPriorityFeePerGas().isEmpty() && callParams.getMaxFeePerGas().isEmpty(); } - private boolean shouldSetMaxFeePerGas(final CallParameter callParams) { + private boolean shouldSetMaxFeePerGas(final CallParameter callParams, final BlockHeader header) { if (protocolSchedule.getChainId().isEmpty()) { return false; } + if (header.getBaseFee().isEmpty()) { + return false; + } + if (shouldSetBlobGasPrice(callParams)) { return true; } From ae4a95306bec74d4d96304564a3a74a742df055c Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Tue, 3 Dec 2024 13:24:05 +1100 Subject: [PATCH 5/9] changelog Signed-off-by: Gabriel-Trintinalia --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c75079be762..9ab90c33e11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ | jvm_memory_pool_bytes_init | jvm_memory_pool_init_bytes | | jvm_memory_pool_bytes_max | jvm_memory_pool_max_bytes | | jvm_memory_pool_bytes_used | jvm_memory_pool_used_bytes | +- Transaction call object cannot have both `gas` and `maxPriorityFeePerGas/maxFeePerGas` fields set [#7965]( https://github.com/hyperledger/besu/pull/7965) ### Upcoming Breaking Changes - Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface. From 6ff82acd37ebca930d644e87dddc6f095498003d Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Tue, 3 Dec 2024 13:49:29 +1100 Subject: [PATCH 6/9] changelog Signed-off-by: Gabriel-Trintinalia --- CHANGELOG.md | 2 +- .../internal/parameters/JsonCallParameter.java | 15 ++++++++------- .../api/jsonrpc/internal/methods/EthCallTest.java | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ab90c33e11..8e309ae3f44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ | jvm_memory_pool_bytes_init | jvm_memory_pool_init_bytes | | jvm_memory_pool_bytes_max | jvm_memory_pool_max_bytes | | jvm_memory_pool_bytes_used | jvm_memory_pool_used_bytes | -- Transaction call object cannot have both `gas` and `maxPriorityFeePerGas/maxFeePerGas` fields set [#7965]( https://github.com/hyperledger/besu/pull/7965) +- Transaction call object cannot have both `gasPrice` and `maxPriorityFeePerGas/maxFeePerGas` fields set [#7965]( https://github.com/hyperledger/besu/pull/7965) ### Upcoming Breaking Changes - Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface. diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java index 9c7f858b4a3..becef60c112 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java @@ -123,11 +123,11 @@ public static final class JsonCallParameterBuilder { private Optional chainId = Optional.empty(); private Address from; private Address to; - private Optional gas = Optional.empty(); + private long gas = -1; private Optional maxPriorityFeePerGas = Optional.empty(); private Optional maxFeePerGas = Optional.empty(); private Optional maxFeePerBlobGas = Optional.empty(); - private Wei gasPrice; + private Optional gasPrice = Optional.empty(); private Wei value; private Bytes data; private Bytes input; @@ -198,7 +198,7 @@ public JsonCallParameterBuilder withTo(final Address to) { */ @JsonDeserialize(using = GasDeserializer.class) public JsonCallParameterBuilder withGas(final Long gas) { - this.gas = Optional.ofNullable(gas); + this.gas = Optional.ofNullable(gas).orElse(-1L); return this; } @@ -253,7 +253,7 @@ public JsonCallParameterBuilder withMaxFeePerBlobGas(final Wei maxFeePerBlobGas) * @return the {@link JsonCallParameterBuilder} instance for chaining */ public JsonCallParameterBuilder withGasPrice(final Wei gasPrice) { - this.gasPrice = gasPrice; + this.gasPrice = Optional.ofNullable(gasPrice); return this; } @@ -361,7 +361,8 @@ public JsonCallParameter build() { throw new IllegalArgumentException("Only one of 'input' or 'data' should be provided"); } - if (gas.isPresent() && (maxFeePerBlobGas.isPresent() || maxPriorityFeePerGas.isPresent())) { + if (gasPrice.isPresent() + && (maxFeePerBlobGas.isPresent() || maxPriorityFeePerGas.isPresent())) { throw new IllegalArgumentException( "both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified"); } @@ -372,8 +373,8 @@ public JsonCallParameter build() { chainId, from, to, - gas.orElse(-1L), - gasPrice, + gas, + gasPrice.orElse(null), maxPriorityFeePerGas, maxFeePerGas, value, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java index d06541a9d60..7de6f65aae2 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java @@ -39,7 +39,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; 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.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.chain.Blockchain; @@ -479,6 +478,7 @@ private JsonCallParameter callParameter( return new JsonCallParameter.JsonCallParameterBuilder() .withFrom(Address.fromHexString("0x0")) .withTo(Address.fromHexString("0x0")) + .withGas(0L) .withGasPrice(gasPrice) .withMaxFeePerGas(maxFeesPerGas) .withMaxPriorityFeePerGas(maxPriorityFeesPerGas) From a244cbb79674647f232b54f8f075c255d31232c2 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Tue, 3 Dec 2024 14:06:23 +1100 Subject: [PATCH 7/9] revert changes Signed-off-by: Gabriel-Trintinalia --- CHANGELOG.md | 1 - .../internal/parameters/JsonCallParameter.java | 12 +++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e309ae3f44..c75079be762 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,6 @@ | jvm_memory_pool_bytes_init | jvm_memory_pool_init_bytes | | jvm_memory_pool_bytes_max | jvm_memory_pool_max_bytes | | jvm_memory_pool_bytes_used | jvm_memory_pool_used_bytes | -- Transaction call object cannot have both `gasPrice` and `maxPriorityFeePerGas/maxFeePerGas` fields set [#7965]( https://github.com/hyperledger/besu/pull/7965) ### Upcoming Breaking Changes - Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface. diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java index becef60c112..85dabda5719 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java @@ -127,7 +127,7 @@ public static final class JsonCallParameterBuilder { private Optional maxPriorityFeePerGas = Optional.empty(); private Optional maxFeePerGas = Optional.empty(); private Optional maxFeePerBlobGas = Optional.empty(); - private Optional gasPrice = Optional.empty(); + private Wei gasPrice; private Wei value; private Bytes data; private Bytes input; @@ -253,7 +253,7 @@ public JsonCallParameterBuilder withMaxFeePerBlobGas(final Wei maxFeePerBlobGas) * @return the {@link JsonCallParameterBuilder} instance for chaining */ public JsonCallParameterBuilder withGasPrice(final Wei gasPrice) { - this.gasPrice = Optional.ofNullable(gasPrice); + this.gasPrice = gasPrice; return this; } @@ -361,12 +361,6 @@ public JsonCallParameter build() { throw new IllegalArgumentException("Only one of 'input' or 'data' should be provided"); } - if (gasPrice.isPresent() - && (maxFeePerBlobGas.isPresent() || maxPriorityFeePerGas.isPresent())) { - throw new IllegalArgumentException( - "both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified"); - } - final Bytes payload = input != null ? input : data; return new JsonCallParameter( @@ -374,7 +368,7 @@ public JsonCallParameter build() { from, to, gas, - gasPrice.orElse(null), + gasPrice, maxPriorityFeePerGas, maxFeePerGas, value, From 3e85149177270d0fb416e0ea4583f6797ebb1346 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Fri, 6 Dec 2024 18:42:52 +1100 Subject: [PATCH 8/9] Changelog Signed-off-by: Gabriel-Trintinalia --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36ff4aa9bba..904746b747a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ ### Additions and Improvements ### Bug fixes +- Correct default parameters for frontier transactions in `eth_call` and `eth_estimateGas` [#7965](https://github.com/hyperledger/besu/pull/7965) ## 24.12.0 @@ -30,7 +31,8 @@ - The `_created` timestamps are not returned by default, you can set the env var `BESU_OPTS="-Dio.prometheus.exporter.includeCreatedTimestamps=true"` to enable them - Some JVM metrics have changed name to adhere to the OTEL standard (see the table below), [Besu Full Grafana dashboard](https://grafana.com/grafana/dashboards/16455-besu-full/) is updated to support both names - | Old Name | New Name | + | Old Name | New Name |Allow frontier simulation when Base Fee is present #7965 + |---------------------------------|---------------------------------| | jvm_memory_bytes_committed | jvm_memory_committed_bytes | | jvm_memory_bytes_init | jvm_memory_init_bytes | From b8765fc9de0c3198241b21990ffe031291a27969 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Fri, 6 Dec 2024 18:44:36 +1100 Subject: [PATCH 9/9] remove link from changelog Signed-off-by: Gabriel-Trintinalia --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 904746b747a..6aca416dbfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,8 +31,7 @@ - The `_created` timestamps are not returned by default, you can set the env var `BESU_OPTS="-Dio.prometheus.exporter.includeCreatedTimestamps=true"` to enable them - Some JVM metrics have changed name to adhere to the OTEL standard (see the table below), [Besu Full Grafana dashboard](https://grafana.com/grafana/dashboards/16455-besu-full/) is updated to support both names - | Old Name | New Name |Allow frontier simulation when Base Fee is present #7965 - + | Old Name | New Name | |---------------------------------|---------------------------------| | jvm_memory_bytes_committed | jvm_memory_committed_bytes | | jvm_memory_bytes_init | jvm_memory_init_bytes |