diff --git a/CHANGELOG.md b/CHANGELOG.md index ba1e2a46e23..e0ad84e1313 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog ## 22.10.4 +### Additions and Improvements +- Add access list to Transaction Call Object [#4802](https://github.com/hyperledger/besu/issues/4801) + ### Breaking Changes ### Additions and Improvements diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCallIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCallIntegrationTest.java index 12467496100..d6559ce893c 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCallIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCallIntegrationTest.java @@ -73,6 +73,7 @@ public void shouldReturnExpectedResultForCallAtLatestBlock() { null, null, Bytes.fromHexString("0x12a7b914"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -96,6 +97,7 @@ public void shouldReturnExpectedResultForCallAtSpecificBlock() { null, null, Bytes.fromHexString("0x12a7b914"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "0x8"); final JsonRpcResponse expectedResponse = @@ -120,6 +122,7 @@ public void shouldReturnSuccessWhenCreatingContract() { null, Bytes.fromHexString( "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -144,6 +147,7 @@ public void shouldReturnErrorWithGasLimitTooLow() { null, null, Bytes.fromHexString("0x12a7b914"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -166,7 +170,8 @@ public void shouldReturnErrorWithGasPriceTooHighAndStrict() { null, null, Bytes.fromHexString("0x12a7b914"), - true); + true, + null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, JsonRpcError.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE); @@ -188,7 +193,8 @@ public void shouldReturnSuccessWithGasPriceTooHighNotStrict() { null, null, Bytes.fromHexString("0x12a7b914"), - false); + false, + null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -211,6 +217,7 @@ public void shouldReturnErrorWithGasPriceTooHigh() { null, null, Bytes.fromHexString("0x12a7b914"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -233,6 +240,7 @@ public void shouldReturnSuccessWithValidGasPrice() { null, null, Bytes.fromHexString("0x12a7b914"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -256,6 +264,7 @@ public void shouldReturnErrorWithGasPriceAndEmptyBalance() { null, null, Bytes.fromHexString("0x12a7b914"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -278,6 +287,7 @@ public void shouldReturnSuccessWithZeroGasPriceAndEmptyBalance() { null, null, Bytes.fromHexString("0x12a7b914"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -301,6 +311,7 @@ public void shouldReturnSuccessWithoutGasPriceAndEmptyBalance() { null, null, Bytes.fromHexString("0x12a7b914"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -324,6 +335,7 @@ public void shouldReturnSuccessWithInvalidGasPricingAndEmptyBalance() { null, null, Bytes.fromHexString("0x12a7b914"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -347,6 +359,7 @@ public void shouldReturnEmptyHashResultForCallWithOnlyToField() { null, null, null, + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x"); diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthEstimateGasIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthEstimateGasIntegrationTest.java index f9e7a0cae5f..e4e86573bc6 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthEstimateGasIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthEstimateGasIntegrationTest.java @@ -64,7 +64,7 @@ public void setUp() { @Test public void shouldReturnExpectedValueForEmptyCallParameter() { final JsonCallParameter callParameter = - new JsonCallParameter(null, null, null, null, null, null, null, null, null); + new JsonCallParameter(null, null, null, null, null, null, null, null, null, null); final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x5208"); @@ -85,6 +85,7 @@ public void shouldReturnExpectedValueForTransfer() { null, Wei.ONE, null, + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x5208"); @@ -107,6 +108,7 @@ public void shouldReturnExpectedValueForContractDeploy() { null, Bytes.fromHexString( "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x1b551"); @@ -129,7 +131,8 @@ public void shouldIgnoreSenderBalanceAccountWhenStrictModeDisabledAndReturnExpec null, Bytes.fromHexString( "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - false); + false, + null); final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x1b551"); @@ -151,7 +154,8 @@ public void shouldNotIgnoreSenderBalanceAccountWhenStrictModeDisabledAndThrowErr null, Bytes.fromHexString( "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - true); + true, + null); final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, JsonRpcError.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE); @@ -163,7 +167,7 @@ public void shouldNotIgnoreSenderBalanceAccountWhenStrictModeDisabledAndThrowErr @Test public void shouldReturnExpectedValueForInsufficientGas() { final JsonCallParameter callParameter = - new JsonCallParameter(null, null, 1L, null, null, null, null, null, null); + new JsonCallParameter(null, null, 1L, null, null, null, null, null, null, null); final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x5208"); diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java index a9918b1f8fb..bae0ef6b639 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java @@ -73,6 +73,7 @@ public void shouldReturnSuccessWithoutGasPriceAndEmptyBalance() { null, null, Bytes.fromHexString("0x2e64cec1"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -96,6 +97,7 @@ public void shouldReturnErrorWithGasPriceTooHigh() { null, null, Bytes.fromHexString("0x2e64cec1"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -118,6 +120,7 @@ public void shouldReturnSuccessWithValidGasPrice() { null, null, Bytes.fromHexString("0x2e64cec1"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -141,6 +144,7 @@ public void shouldReturnErrorWithGasPriceLessThanCurrentBaseFee() { null, null, Bytes.fromHexString("0x2e64cec1"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -163,6 +167,7 @@ public void shouldReturnSuccessWithValidMaxFeePerGas() { Wei.fromHexString("0x3B9ACA01"), null, Bytes.fromHexString("0x2e64cec1"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -186,6 +191,7 @@ public void shouldReturnSuccessWithValidMaxFeePerGasAndMaxPriorityFeePerGas() { Wei.fromHexString("0x3B9ACA01"), null, Bytes.fromHexString("0x2e64cec1"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -209,6 +215,7 @@ public void shouldReturnErrorWithValidMaxFeePerGasLessThanCurrentBaseFee() { Wei.fromHexString("0x0A"), null, Bytes.fromHexString("0x2e64cec1"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -231,6 +238,7 @@ public void shouldReturnErrorWithValidMaxFeePerGasLessThanMaxPriorityFeePerGas() Wei.fromHexString("0x3B9ACA01"), null, Bytes.fromHexString("0x2e64cec1"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = @@ -254,6 +262,7 @@ public void shouldReturnErrorWithMaxFeePerGasAndEmptyBalance() { Wei.fromHexString("0x3B9ACA01"), null, Bytes.fromHexString("0x2e64cec1"), + null, null); final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = 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 new file mode 100644 index 00000000000..19998344a99 --- /dev/null +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java @@ -0,0 +1,159 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.api.jsonrpc.methods.fork.london; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.api.jsonrpc.BlockchainImporter; +import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcTestMethodsFactory; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.evm.AccessListEntry; +import org.hyperledger.besu.testutil.BlockTestUtil; + +import java.util.List; +import java.util.Map; + +import com.google.common.base.Charsets; +import com.google.common.io.Resources; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class EthEstimateGasIntegrationTest { + + private final String METHOD_NAME = "eth_estimateGas"; + + private static JsonRpcTestMethodsFactory BLOCKCHAIN; + + private JsonRpcMethod method; + + @BeforeAll + public static void setUpOnce() throws Exception { + final String genesisJson = + Resources.toString(BlockTestUtil.getTestLondonGenesisUrl(), Charsets.UTF_8); + + BLOCKCHAIN = + new JsonRpcTestMethodsFactory( + new BlockchainImporter(BlockTestUtil.getTestLondonBlockchainUrl(), genesisJson)); + } + + @BeforeEach + public void setUp() { + final Map methods = BLOCKCHAIN.methods(); + method = methods.get(METHOD_NAME); + } + + @Test + public void shouldReturnExpectedValueForTransfer() { + final JsonCallParameter callParameter = + new JsonCallParameter( + Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), + Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"), + null, + null, + null, + null, + Wei.ONE, + null, + null, + null); + + final JsonRpcResponse response = method.response(requestWithParams(callParameter)); + final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x5208"); + assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); + } + + @Test + public void shouldReturnExpectedValueForTransfer_WithAccessList() { + + final JsonCallParameter callParameter = + new JsonCallParameter( + Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), + Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"), + null, + null, + null, + null, + Wei.ONE, + null, + null, + createAccessList()); + + final JsonRpcResponse response = method.response(requestWithParams(callParameter)); + final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x62d4"); + assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); + } + + @Test + public void shouldReturnExpectedValueForContractDeploy() { + final JsonCallParameter callParameter = + new JsonCallParameter( + Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), + null, + null, + null, + null, + null, + null, + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), + null, + null); + final JsonRpcResponse response = method.response(requestWithParams(callParameter)); + final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x1f081"); + assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); + } + + @Test + public void shouldReturnExpectedValueForContractDeploy_WithAccessList() { + final JsonCallParameter callParameter = + new JsonCallParameter( + Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), + null, + null, + null, + null, + null, + null, + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), + null, + createAccessList()); + + final JsonRpcResponse response = method.response(requestWithParams(callParameter)); + final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x2014d"); + assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); + } + + private List createAccessList() { + return List.of( + new AccessListEntry( + Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"), + List.of(Bytes32.ZERO))); + } + + private JsonRpcRequestContext requestWithParams(final Object... params) { + return new JsonRpcRequestContext(new JsonRpcRequest("2.0", METHOD_NAME, params)); + } +} 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 6135a409f30..957a6e98551 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 @@ -237,7 +237,8 @@ private Optional executeCall(final DataFetchingEnvironment environme maxPriorityFeePerGas, maxFeePerGas, valueParam, - data); + data, + Optional.empty()); final Optional opt = transactionSimulator.process( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java index e3b0930ea63..29bb816407d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java @@ -105,7 +105,8 @@ private CallParameter overrideGasLimitAndPrice( callParams.getMaxPriorityFeePerGas(), callParams.getMaxFeePerGas(), callParams.getValue(), - callParams.getPayload()); + callParams.getPayload(), + callParams.getAccessList()); } private Function gasEstimateResponse( 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 e8b35573323..bbcc2ee2e72 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 @@ -19,7 +19,9 @@ import org.hyperledger.besu.ethereum.core.json.HexLongDeserializer; import org.hyperledger.besu.ethereum.core.json.HexStringDeserializer; import org.hyperledger.besu.ethereum.transaction.CallParameter; +import org.hyperledger.besu.evm.AccessListEntry; +import java.util.List; import java.util.Optional; import com.fasterxml.jackson.annotation.JsonAnySetter; @@ -49,7 +51,8 @@ public JsonCallParameter( @JsonProperty("value") final Wei value, @JsonDeserialize(using = HexStringDeserializer.class) @JsonProperty("data") final Bytes payload, - @JsonProperty("strict") final Boolean strict) { + @JsonProperty("strict") final Boolean strict, + @JsonProperty("accessList") final List accessList) { super( from, to, @@ -58,7 +61,8 @@ public JsonCallParameter( Optional.ofNullable(maxPriorityFeePerGas), Optional.ofNullable(maxFeePerGas), value, - payload); + payload, + Optional.ofNullable(accessList)); this.strict = Optional.ofNullable(strict); } 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 cd649a32191..d8c79be5c69 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 @@ -95,7 +95,7 @@ public void shouldReturnInternalErrorWhenProcessorReturnsEmpty() { @Test public void shouldAcceptRequestWhenMissingOptionalFields() { final JsonCallParameter callParameter = - new JsonCallParameter(null, null, null, null, null, null, null, null, null); + new JsonCallParameter(null, null, null, null, null, null, null, null, null, null); final JsonRpcRequestContext request = ethCallRequest(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Bytes.of().toString()); @@ -262,6 +262,7 @@ private JsonCallParameter callParameter( maxPriorityFeesPerGas, Wei.ZERO, Bytes.EMPTY, + null, null); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java index a9f26f57b10..7280560a5ac 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java @@ -359,7 +359,8 @@ private JsonCallParameter legacyTransactionCallParameter( null, Wei.ZERO, Bytes.EMPTY, - isStrict); + isStrict, + null); } private CallParameter modifiedLegacyTransactionCallParameter(final Wei gasPrice) { @@ -371,7 +372,8 @@ private CallParameter modifiedLegacyTransactionCallParameter(final Wei gasPrice) Optional.empty(), Optional.empty(), Wei.ZERO, - Bytes.EMPTY); + Bytes.EMPTY, + Optional.empty()); } private CallParameter eip1559TransactionCallParameter() { @@ -388,7 +390,8 @@ private JsonCallParameter eip1559TransactionCallParameter(final Optional ga Wei.fromHexString("0x10"), Wei.ZERO, Bytes.EMPTY, - false); + false, + null); } private CallParameter modifiedEip1559TransactionCallParameter() { @@ -400,7 +403,8 @@ private CallParameter modifiedEip1559TransactionCallParameter() { Optional.of(Wei.fromHexString("0x10")), Optional.of(Wei.fromHexString("0x10")), Wei.ZERO, - Bytes.EMPTY); + Bytes.EMPTY, + Optional.empty()); } private JsonRpcRequestContext ethEstimateGasRequest(final CallParameter callParameter) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java index 91a14e5163b..1c447360b74 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java @@ -84,6 +84,7 @@ public void shouldThrowInvalidJsonRpcParametersExceptionWhenMissingToField() { null, Wei.ZERO, Bytes.EMPTY, + null, null); final JsonRpcRequestContext request = ethCallRequest(privacyGroupId, callParameter, "latest"); @@ -110,7 +111,7 @@ public void shouldReturnNullWhenProcessorReturnsEmpty() { public void shouldAcceptRequestWhenMissingOptionalFields() { final JsonCallParameter callParameter = new JsonCallParameter( - null, Address.fromHexString("0x0"), null, null, null, null, null, null, null); + null, Address.fromHexString("0x0"), null, null, null, null, null, null, null, null); final JsonRpcRequestContext request = ethCallRequest(privacyGroupId, callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Bytes.of().toString()); @@ -189,6 +190,7 @@ private JsonCallParameter callParameter() { null, Wei.ZERO, Bytes.EMPTY, + null, null); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/CallParameter.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/CallParameter.java index b9dda8a8a57..dbf5eb249e5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/CallParameter.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/CallParameter.java @@ -17,7 +17,9 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.evm.AccessListEntry; +import java.util.List; import java.util.Objects; import java.util.Optional; @@ -42,6 +44,8 @@ public class CallParameter { private final Bytes payload; + private final Optional> accessList; + public CallParameter( final Address from, final Address to, @@ -52,6 +56,7 @@ public CallParameter( this.from = from; this.to = to; this.gasLimit = gasLimit; + this.accessList = Optional.empty(); this.maxPriorityFeePerGas = Optional.empty(); this.maxFeePerGas = Optional.empty(); this.gasPrice = gasPrice; @@ -67,7 +72,8 @@ public CallParameter( final Optional maxPriorityFeePerGas, final Optional maxFeePerGas, final Wei value, - final Bytes payload) { + final Bytes payload, + final Optional> accessList) { this.from = from; this.to = to; this.gasLimit = gasLimit; @@ -76,6 +82,7 @@ public CallParameter( this.gasPrice = gasPrice; this.value = value; this.payload = payload; + this.accessList = accessList; } public Address getFrom() { @@ -110,6 +117,10 @@ public Bytes getPayload() { return payload; } + public Optional> getAccessList() { + return accessList; + } + @Override public boolean equals(final Object o) { if (this == o) { @@ -144,6 +155,7 @@ public static CallParameter fromTransaction(final Transaction tx) { Optional.of(Wei.fromQuantity(tx.getMaxPriorityFeePerGas().orElseGet(() -> Wei.ZERO))), tx.getMaxFeePerGas(), Wei.fromQuantity(tx.getValue()), - tx.getPayload()); + tx.getPayload(), + tx.getAccessList()); } } 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 3ac19c03d55..4f96b5c7239 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 @@ -144,7 +144,7 @@ public Optional process( return Optional.empty(); } - try (var ws = getWorldState(header)) { + try (final var ws = getWorldState(header)) { WorldUpdater updater = getEffectiveWorldStateUpdater(header, ws); @@ -282,6 +282,9 @@ private Optional buildTransaction( .payload(payload) .signature(FAKE_SIGNATURE); + // Set access list if present + callParams.getAccessList().ifPresent(transactionBuilder::accessList); + final Wei gasPrice; final Wei maxFeePerGas; final Wei maxPriorityFeePerGas; @@ -309,6 +312,7 @@ private Optional buildTransaction( .getChainId() .orElse(BigInteger.ONE)); // needed to make some transactions valid } + final Transaction transaction = transactionBuilder.build(); return Optional.ofNullable(transaction); } @@ -337,7 +341,7 @@ public Optional doesAddressExistAtHead(final Address address) { .getMutable(header.getStateRoot(), header.getHash(), false) .orElseThrow()) { return doesAddressExist(worldState, address, header); - } catch (Exception ex) { + } catch (final Exception ex) { return Optional.empty(); } } 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 79c03d3e714..5309ae7307e 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 @@ -589,6 +589,7 @@ private CallParameter eip1559TransactionCallParameter( Optional.of(maxFeePerGas), Optional.of(maxPriorityFeePerGas), Wei.of(0), - Bytes.EMPTY); + Bytes.EMPTY, + Optional.empty()); } }