From 335e2da61e7918bb1a9fadf2c0b1f1cf7706eb49 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Thu, 17 Aug 2023 16:29:27 +0100 Subject: [PATCH 1/9] Initial commit with new JSON/RPC method Signed-off-by: Matthew Whitehead --- .../besu/ethereum/api/jsonrpc/RpcMethod.java | 1 + .../internal/methods/EthGetBlockReceipts.java | 96 +++++++++++++++++++ .../internal/results/BlockReceiptsResult.java | 34 +++++++ .../jsonrpc/methods/EthJsonRpcMethods.java | 4 +- 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockReceiptsResult.java diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 5b510cb8e71..a0ee64a69c0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -97,6 +97,7 @@ public enum RpcMethod { ETH_GET_BALANCE("eth_getBalance"), ETH_GET_BLOCK_BY_HASH("eth_getBlockByHash"), ETH_GET_BLOCK_BY_NUMBER("eth_getBlockByNumber"), + ETH_GET_BLOCK_RECEIPTS("eth_getBlockReceipts"), ETH_GET_BLOCK_TRANSACTION_COUNT_BY_HASH("eth_getBlockTransactionCountByHash"), ETH_GET_BLOCK_TRANSACTION_COUNT_BY_NUMBER("eth_getBlockTransactionCountByNumber"), ETH_GET_CODE("eth_getCode"), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java new file mode 100644 index 00000000000..ad3fed007b7 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java @@ -0,0 +1,96 @@ +/* + * Copyright Hyperledger Besu contributors + * + * 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.internal.methods; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockReceiptsResult; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptResult; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptRootResult; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptStatusResult; +import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata; +import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; +import org.hyperledger.besu.ethereum.api.query.TransactionReceiptWithMetadata; +import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.TransactionReceiptType; + +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import com.google.common.base.Suppliers; + +public class EthGetBlockReceipts extends AbstractBlockParameterOrBlockHashMethod { + + private final ProtocolSchedule protocolSchedule; + + public EthGetBlockReceipts( + final BlockchainQueries blockchain, final ProtocolSchedule protocolSchedule) { + this(Suppliers.ofInstance(blockchain), protocolSchedule); + } + + public EthGetBlockReceipts( + final Supplier blockchain, final ProtocolSchedule protocolSchedule) { + super(blockchain); + this.protocolSchedule = protocolSchedule; + } + + @Override + public String getName() { + return RpcMethod.ETH_GET_BLOCK_RECEIPTS.getMethodName(); + } + + @Override + protected BlockParameterOrBlockHash blockParameterOrBlockHash( + final JsonRpcRequestContext request) { + return request.getRequiredParameter(0, BlockParameterOrBlockHash.class); + } + + @Override + protected Object resultByBlockHash(final JsonRpcRequestContext request, final Hash blockHash) { + return getBlockReceiptsResult(blockHash); + } + + private Optional txReceipt(final TransactionWithMetadata tx) { + Optional receipt = + blockchainQueries + .get() + .transactionReceiptByTransactionHash(tx.getTransaction().getHash(), protocolSchedule); + if (receipt.isPresent()) { + if (receipt.get().getReceipt().getTransactionReceiptType() == TransactionReceiptType.ROOT) { + return Optional.of(new TransactionReceiptRootResult(receipt.get())); + } else { + return Optional.of(new TransactionReceiptStatusResult(receipt.get())); + } + } + return Optional.empty(); + } + + private BlockReceiptsResult getBlockReceiptsResult(final Hash blockHash) { + BlockchainQueries blockchain = blockchainQueries.get(); + BlockWithMetadata theBlock = + blockchain.blockByHash(blockHash).get(); + final List txs2 = + theBlock.getTransactions().stream() + .map(tx -> txReceipt(tx).get()) + .collect(Collectors.toList()); + + return new BlockReceiptsResult(txs2); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockReceiptsResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockReceiptsResult.java new file mode 100644 index 00000000000..2a239bdd3cb --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockReceiptsResult.java @@ -0,0 +1,34 @@ +/* + * Copyright Hyperledger Besu contributors + * + * 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.internal.results; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** The result set from querying the receipts for a given block. */ +public class BlockReceiptsResult { + + private final List results; + + public BlockReceiptsResult(final List receipts) { + results = receipts; + } + + @JsonValue + public List getResults() { + return results; + } +} 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 938e3f62c94..b3ca5514d7b 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 @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * Copyright Hyperledger Besu contributors * * 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 @@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBalance; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBlockByHash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBlockByNumber; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBlockReceipts; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBlockTransactionCountByHash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBlockTransactionCountByNumber; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetCode; @@ -119,6 +120,7 @@ protected Map create() { new EthGetBalance(blockchainQueries), new EthGetBlockByHash(blockchainQueries, blockResult), new EthGetBlockByNumber(blockchainQueries, blockResult, synchronizer), + new EthGetBlockReceipts(blockchainQueries, protocolSchedule), new EthGetBlockTransactionCountByNumber(blockchainQueries), new EthGetBlockTransactionCountByHash(blockchainQueries), new EthCall( From da1a3239f728f3722933c06f4964ef6443cfd935 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Mon, 21 Aug 2023 11:55:30 +0100 Subject: [PATCH 2/9] Add unit tests Signed-off-by: Matthew Whitehead --- CHANGELOG.md | 1 + .../internal/methods/EthGetBlockReceipts.java | 32 ++-- .../methods/EthGetBlockReceiptsTest.java | 154 ++++++++++++++++++ 3 files changed, 171 insertions(+), 16 deletions(-) create mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 55c539ed2e9..929e2d9194c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Add ABI-decoded revert reason to `eth_call` and `eth_estimateGas` responses [#5705](https://github.com/hyperledger/besu/issues/5705) ### Additions and Improvements +- New `eth_getBlockReceipts` JSON/RPC method to retrieve all receipts for a block in a single call [#5771](https://github.com/hyperledger/besu/pull/5771) ### Bug Fixes - Make smart contract permissioning features work with london fork [#5727](https://github.com/hyperledger/besu/pull/5727) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java index ad3fed007b7..92b3eb54542 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java @@ -22,16 +22,15 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptRootResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptStatusResult; -import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.query.TransactionReceiptWithMetadata; import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.TransactionReceiptType; +import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.function.Supplier; import java.util.stream.Collectors; import com.google.common.base.Suppliers; @@ -42,12 +41,7 @@ public class EthGetBlockReceipts extends AbstractBlockParameterOrBlockHashMethod public EthGetBlockReceipts( final BlockchainQueries blockchain, final ProtocolSchedule protocolSchedule) { - this(Suppliers.ofInstance(blockchain), protocolSchedule); - } - - public EthGetBlockReceipts( - final Supplier blockchain, final ProtocolSchedule protocolSchedule) { - super(blockchain); + super(Suppliers.ofInstance(blockchain)); this.protocolSchedule = protocolSchedule; } @@ -67,6 +61,9 @@ protected Object resultByBlockHash(final JsonRpcRequestContext request, final Ha return getBlockReceiptsResult(blockHash); } + /* + * For a given transaction, get its receipt and if it exists, wrap in a transaction receipt of the correct type + */ private Optional txReceipt(final TransactionWithMetadata tx) { Optional receipt = blockchainQueries @@ -83,14 +80,17 @@ private Optional txReceipt(final TransactionWithMetada } private BlockReceiptsResult getBlockReceiptsResult(final Hash blockHash) { - BlockchainQueries blockchain = blockchainQueries.get(); - BlockWithMetadata theBlock = - blockchain.blockByHash(blockHash).get(); - final List txs2 = - theBlock.getTransactions().stream() - .map(tx -> txReceipt(tx).get()) - .collect(Collectors.toList()); + final List receiptList = + blockchainQueries + .get() + .blockByHash(blockHash) + .map( + block -> + block.getTransactions().stream() + .map(tx -> txReceipt(tx).get()) + .collect(Collectors.toList())) + .orElse(new ArrayList<>()); - return new BlockReceiptsResult(txs2); + return new BlockReceiptsResult(receiptList); } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java new file mode 100644 index 00000000000..19ac8eca8f3 --- /dev/null +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java @@ -0,0 +1,154 @@ +/* + * 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.internal.methods; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import org.hyperledger.besu.datatypes.Hash; +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.exception.InvalidJsonRpcParameters; +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.BlockReceiptsResult; +import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; +import org.hyperledger.besu.ethereum.chain.MutableBlockchain; +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.core.BlockDataGenerator; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; + +import java.util.List; + +import org.apache.tuweni.bytes.Bytes32; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class EthGetBlockReceiptsTest { + + private static final int BLOCKCHAIN_LENGTH = 5; + private static final String ZERO_HASH = String.valueOf(Hash.ZERO); + private static final String HASH_63_CHARS_LONG = + "0xd3d3d1340c085e1b14182e01fd0b7cc5b585dca77f809f78fcca3e1a165b189"; + private static final String RANDOM_HASH = Hash.wrap(Bytes32.random()).toString(); + private static final String ETH_METHOD = "eth_getBlockReceipts"; + private static final String JSON_RPC_VERSION = "2.0"; + + @Mock private BlockchainQueries blockchainQueries; + @Mock private WorldStateArchive worldStateArchive; + private MutableBlockchain blockchain; + private static final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); + private EthGetBlockReceipts method; + private ProtocolSchedule protocolSchedule; + final JsonRpcResponse blockNotFoundResponse = + new JsonRpcErrorResponse(null, RpcErrorType.BLOCK_NOT_FOUND); + + @BeforeEach + public void setUp() { + blockchain = createInMemoryBlockchain(blockDataGenerator.genesisBlock()); + + for (int i = 1; i < BLOCKCHAIN_LENGTH; i++) { + final BlockDataGenerator.BlockOptions options = + new BlockDataGenerator.BlockOptions() + .setBlockNumber(i) + .setParentHash(blockchain.getBlockHashByNumber(i - 1).orElseThrow()); + final Block block = blockDataGenerator.block(options); + final List receipts = blockDataGenerator.receipts(block); + + blockchain.appendBlock(block, receipts); + } + + blockchainQueries = spy(new BlockchainQueries(blockchain, worldStateArchive)); + protocolSchedule = mock(ProtocolSchedule.class); + method = new EthGetBlockReceipts(blockchainQueries, protocolSchedule); + } + + @Test + public void returnsCorrectMethodName() { + assertThat(method.getName()).isEqualTo(ETH_METHOD); + } + + @Test + public void exceptionWhenNoParamsSupplied() { + assertThatThrownBy(() -> method.response(requestWithParams())) + .isInstanceOf(InvalidJsonRpcParameters.class) + .hasMessage("Missing required json rpc parameter at index 0"); + verifyNoMoreInteractions(blockchainQueries); + } + + @Test + public void exceptionWhenBlockNumberTooLarge() { + assertThatThrownBy(() -> method.response(requestWithParams("0x1212121212121212121212"))) + .isInstanceOf(InvalidJsonRpcParameters.class); + verifyNoMoreInteractions(blockchainQueries); + } + + @Test + public void twoReceiptsForLatestBlock() { + /* Block generator defaults to 2 transactions per mocked block */ + JsonRpcResponse actualResponse = method.response(requestWithParams("latest")); + assertThat(actualResponse).isInstanceOf(JsonRpcSuccessResponse.class); + final BlockReceiptsResult result = + (BlockReceiptsResult) ((JsonRpcSuccessResponse) actualResponse).getResult(); + assertThat(result.getResults().size()).isEqualTo(2); + } + + @Test + public void twoReceiptsForBlockN() { + /* Block generator defaults to 2 transactions per mocked block */ + JsonRpcResponse actualResponse = method.response(requestWithParams("0x01")); + assertThat(actualResponse).isInstanceOf(JsonRpcSuccessResponse.class); + final BlockReceiptsResult result = + (BlockReceiptsResult) ((JsonRpcSuccessResponse) actualResponse).getResult(); + assertThat(result.getResults().size()).isEqualTo(2); + } + + @Test + public void blockNotFoundWhenHash63CharsLong() { + /* Valid hash with 63 chars in - should result in block not found */ + JsonRpcResponse actualResponse = method.response(requestWithParams(HASH_63_CHARS_LONG)); + assertThat(actualResponse).usingRecursiveComparison().isEqualTo(blockNotFoundResponse); + } + + @Test + public void blockNotFoundForRandomHash() { + /* Valid random hash - should result in block not found (effectively impossible for it to be a valid block) */ + JsonRpcResponse actualResponse = method.response(requestWithParams(RANDOM_HASH)); + assertThat(actualResponse).usingRecursiveComparison().isEqualTo(blockNotFoundResponse); + } + + @Test + public void blockNotFoundForZeroHash() { + /* Zero hash - should result in block not found */ + JsonRpcResponse actualResponse = method.response(requestWithParams(ZERO_HASH)); + assertThat(actualResponse).usingRecursiveComparison().isEqualTo(blockNotFoundResponse); + } + + private JsonRpcRequestContext requestWithParams(final Object... params) { + return new JsonRpcRequestContext(new JsonRpcRequest(JSON_RPC_VERSION, ETH_METHOD, params)); + } +} From 21727e8779c2cbe5f02a462daa6f96ce6d2c9876 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Mon, 21 Aug 2023 11:59:54 +0100 Subject: [PATCH 3/9] New copyright header Signed-off-by: Matthew Whitehead --- .../api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java index 19ac8eca8f3..f7bb47742c8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * Copyright Hyperledger Besu contributors * * 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 From 8e6565c5427568aca2ca60dfb87383961dc47a4b Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Tue, 22 Aug 2023 11:28:50 +0100 Subject: [PATCH 4/9] Update unit tests Signed-off-by: Matthew Whitehead --- .../methods/EthGetBlockReceiptsTest.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java index f7bb47742c8..5893171bb93 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java @@ -30,6 +30,7 @@ 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.BlockReceiptsResult; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.Block; @@ -114,17 +115,47 @@ public void twoReceiptsForLatestBlock() { assertThat(actualResponse).isInstanceOf(JsonRpcSuccessResponse.class); final BlockReceiptsResult result = (BlockReceiptsResult) ((JsonRpcSuccessResponse) actualResponse).getResult(); + assertThat(result.getResults().size()).isEqualTo(2); + + // Check TX1 receipt is correct + TransactionReceiptResult tx1 = result.getResults().get(0); + assertThat(tx1.getBlockNumber()).isEqualTo("0x4"); + assertThat(tx1.getEffectiveGasPrice()).isEqualTo("0x8331b584"); + assertThat(tx1.getTo()).isEqualTo("0xffa87762dcd4bbf2d6b22390e68c1915d89292ae"); + assertThat(tx1.getType()).isEqualTo("0x0"); + + // Check TX2 receipt is correct + TransactionReceiptResult tx2 = result.getResults().get(1); + assertThat(tx2.getBlockNumber()).isEqualTo("0x4"); + assertThat(tx2.getEffectiveGasPrice()).isEqualTo("0x9f7cd42"); + assertThat(tx2.getTo()).isEqualTo("0x46530778ec4a61cbea38698d2efc0c618ea0641f"); + assertThat(tx2.getType()).isEqualTo("0x2"); } @Test - public void twoReceiptsForBlockN() { + public void twoReceiptsForBlockOne() { /* Block generator defaults to 2 transactions per mocked block */ JsonRpcResponse actualResponse = method.response(requestWithParams("0x01")); assertThat(actualResponse).isInstanceOf(JsonRpcSuccessResponse.class); final BlockReceiptsResult result = (BlockReceiptsResult) ((JsonRpcSuccessResponse) actualResponse).getResult(); + assertThat(result.getResults().size()).isEqualTo(2); + + // Check TX1 receipt is correct + TransactionReceiptResult tx1 = result.getResults().get(0); + assertThat(tx1.getBlockNumber()).isEqualTo("0x1"); + assertThat(tx1.getEffectiveGasPrice()).isEqualTo("0xf6c116f8"); + assertThat(tx1.getTo()).isEqualTo("0xc7334b4639e5640d8cc44a6a17e14e78f99e0832"); + assertThat(tx1.getType()).isEqualTo("0x1"); + + // Check TX2 receipt is correct + TransactionReceiptResult tx2 = result.getResults().get(1); + assertThat(tx2.getBlockNumber()).isEqualTo("0x1"); + assertThat(tx2.getEffectiveGasPrice()).isEqualTo("0x2e29575b"); + assertThat(tx2.getTo()).isEqualTo("0xed195a8b41b32a1b43e1a9b322fe5bfc4c71dc2e"); + assertThat(tx2.getType()).isEqualTo("0x2"); } @Test From 6b33163aae85c3ef882c5545a4083946f4702e00 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Tue, 22 Aug 2023 12:48:28 +0100 Subject: [PATCH 5/9] Fix unit tests Signed-off-by: Matthew Whitehead --- .../internal/methods/EthGetBlockReceiptsTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java index 5893171bb93..4a2429d9a87 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java @@ -146,15 +146,15 @@ public void twoReceiptsForBlockOne() { // Check TX1 receipt is correct TransactionReceiptResult tx1 = result.getResults().get(0); assertThat(tx1.getBlockNumber()).isEqualTo("0x1"); - assertThat(tx1.getEffectiveGasPrice()).isEqualTo("0xf6c116f8"); - assertThat(tx1.getTo()).isEqualTo("0xc7334b4639e5640d8cc44a6a17e14e78f99e0832"); - assertThat(tx1.getType()).isEqualTo("0x1"); + assertThat(tx1.getEffectiveGasPrice()).isEqualTo("0x4a7ebf2e"); + assertThat(tx1.getTo()).isEqualTo("0x6ada2e11049e5fc54fcdf2a97996d9b2aa80fe71"); + assertThat(tx1.getType()).isEqualTo("0x2"); // Check TX2 receipt is correct TransactionReceiptResult tx2 = result.getResults().get(1); assertThat(tx2.getBlockNumber()).isEqualTo("0x1"); - assertThat(tx2.getEffectiveGasPrice()).isEqualTo("0x2e29575b"); - assertThat(tx2.getTo()).isEqualTo("0xed195a8b41b32a1b43e1a9b322fe5bfc4c71dc2e"); + assertThat(tx2.getEffectiveGasPrice()).isEqualTo("0xa6e00cb5"); + assertThat(tx2.getTo()).isEqualTo("0x429b96f49fb2e74ba0fda06cf6f380caffc2fac2"); assertThat(tx2.getType()).isEqualTo("0x2"); } From b7cdfa466543fd25d30873a8f831451357fa7d39 Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Wed, 23 Aug 2023 08:40:15 +0100 Subject: [PATCH 6/9] Update ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java Co-authored-by: Sally MacFarlane Signed-off-by: Matt Whitehead --- .../api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java index 4a2429d9a87..50feb217fd7 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java @@ -135,7 +135,7 @@ public void twoReceiptsForLatestBlock() { @Test public void twoReceiptsForBlockOne() { - /* Block generator defaults to 2 transactions per mocked block */ + /* Block generator defaults to 2 transactions per block */ JsonRpcResponse actualResponse = method.response(requestWithParams("0x01")); assertThat(actualResponse).isInstanceOf(JsonRpcSuccessResponse.class); final BlockReceiptsResult result = From a78e7ac134aaa8f167b88cf5dbe8480c2d6da53c Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Wed, 23 Aug 2023 08:40:27 +0100 Subject: [PATCH 7/9] Update CHANGELOG.md Co-authored-by: Sally MacFarlane Signed-off-by: Matt Whitehead --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5777b275b80..6eec8fa50fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ### Additions and Improvements - Added `benchmark` subcommand to `evmtool` [#5754](https://github.com/hyperledger/besu/issues/5754) - JSON output is now compact by default. This can be overridden by the new `--json-pretty-print-enabled` CLI option. [#5766](https://github.com/hyperledger/besu/pull/5766) -- New `eth_getBlockReceipts` JSON/RPC method to retrieve all receipts for a block in a single call [#5771](https://github.com/hyperledger/besu/pull/5771) +- New `eth_getBlockReceipts` JSON-RPC method to retrieve all transaction receipts for a block in a single call [#5771](https://github.com/hyperledger/besu/pull/5771) ### Bug Fixes - Make smart contract permissioning features work with london fork [#5727](https://github.com/hyperledger/besu/pull/5727) From b5cb9020ffbaa3bd27fb97072b7e294f8fd4fda5 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Wed, 23 Aug 2023 10:30:16 +0100 Subject: [PATCH 8/9] Update unit tests to check receipts against generated blockchain transactions at runtime. Add getEthSerializedType() utility to TransactionType. Signed-off-by: Matthew Whitehead --- .../besu/datatypes/TransactionType.java | 11 ++++ .../methods/EthGetBlockReceiptsTest.java | 56 +++++++++++-------- .../TransactionAnnouncementEncoder.java | 4 +- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java index b100240058c..984a4cc7467 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java @@ -50,6 +50,17 @@ public byte getSerializedType() { return (byte) this.typeValue; } + /** + * Gets serialized type for returning in an eth transaction result, factoring in the special case + * for FRONTIER transactions which have enum type 0xf8 but are represented as 0x00 in transaction + * results. + * + * @return the serialized type + */ + public byte getEthSerializedType() { + return (this == FRONTIER ? 0x00 : this.getSerializedType()); + } + /** * Compare to serialized type. * diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java index 50feb217fd7..dad5099ee7c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java @@ -35,13 +35,13 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockDataGenerator; +import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import java.util.List; -import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -55,7 +55,6 @@ public class EthGetBlockReceiptsTest { private static final String ZERO_HASH = String.valueOf(Hash.ZERO); private static final String HASH_63_CHARS_LONG = "0xd3d3d1340c085e1b14182e01fd0b7cc5b585dca77f809f78fcca3e1a165b189"; - private static final String RANDOM_HASH = Hash.wrap(Bytes32.random()).toString(); private static final String ETH_METHOD = "eth_getBlockReceipts"; private static final String JSON_RPC_VERSION = "2.0"; @@ -110,6 +109,13 @@ public void exceptionWhenBlockNumberTooLarge() { @Test public void twoReceiptsForLatestBlock() { + + // Read expected transactions from the generated blockchain + final Transaction expectedTx1 = + blockchain.getBlockByNumber(BLOCKCHAIN_LENGTH - 1).get().getBody().getTransactions().get(0); + final Transaction expectedTx2 = + blockchain.getBlockByNumber(BLOCKCHAIN_LENGTH - 1).get().getBody().getTransactions().get(1); + /* Block generator defaults to 2 transactions per mocked block */ JsonRpcResponse actualResponse = method.response(requestWithParams("latest")); assertThat(actualResponse).isInstanceOf(JsonRpcSuccessResponse.class); @@ -120,21 +126,30 @@ public void twoReceiptsForLatestBlock() { // Check TX1 receipt is correct TransactionReceiptResult tx1 = result.getResults().get(0); - assertThat(tx1.getBlockNumber()).isEqualTo("0x4"); - assertThat(tx1.getEffectiveGasPrice()).isEqualTo("0x8331b584"); - assertThat(tx1.getTo()).isEqualTo("0xffa87762dcd4bbf2d6b22390e68c1915d89292ae"); - assertThat(tx1.getType()).isEqualTo("0x0"); + assertThat(tx1.getBlockNumber()).isEqualTo("0x" + (BLOCKCHAIN_LENGTH - 1)); + assertThat(tx1.getEffectiveGasPrice()).isNotEmpty(); + assertThat(tx1.getTo()).isEqualTo(expectedTx1.getTo().get().toString()); + assertThat(tx1.getType()) + .isEqualTo(String.format("0x%X", expectedTx1.getType().getEthSerializedType())); // Check TX2 receipt is correct TransactionReceiptResult tx2 = result.getResults().get(1); - assertThat(tx2.getBlockNumber()).isEqualTo("0x4"); - assertThat(tx2.getEffectiveGasPrice()).isEqualTo("0x9f7cd42"); - assertThat(tx2.getTo()).isEqualTo("0x46530778ec4a61cbea38698d2efc0c618ea0641f"); - assertThat(tx2.getType()).isEqualTo("0x2"); + assertThat(tx2.getBlockNumber()).isEqualTo("0x" + (BLOCKCHAIN_LENGTH - 1)); + assertThat(tx2.getEffectiveGasPrice()).isNotEmpty(); + assertThat(tx2.getTo()).isEqualTo(expectedTx2.getTo().get().toString()); + assertThat(tx2.getType()) + .isEqualTo(String.format("0x%X", expectedTx2.getType().getEthSerializedType())); } @Test public void twoReceiptsForBlockOne() { + + // Read expected transactions from the generated blockchain + final Transaction expectedTx1 = + blockchain.getBlockByNumber(1).get().getBody().getTransactions().get(0); + final Transaction expectedTx2 = + blockchain.getBlockByNumber(1).get().getBody().getTransactions().get(1); + /* Block generator defaults to 2 transactions per block */ JsonRpcResponse actualResponse = method.response(requestWithParams("0x01")); assertThat(actualResponse).isInstanceOf(JsonRpcSuccessResponse.class); @@ -146,16 +161,18 @@ public void twoReceiptsForBlockOne() { // Check TX1 receipt is correct TransactionReceiptResult tx1 = result.getResults().get(0); assertThat(tx1.getBlockNumber()).isEqualTo("0x1"); - assertThat(tx1.getEffectiveGasPrice()).isEqualTo("0x4a7ebf2e"); - assertThat(tx1.getTo()).isEqualTo("0x6ada2e11049e5fc54fcdf2a97996d9b2aa80fe71"); - assertThat(tx1.getType()).isEqualTo("0x2"); + assertThat(tx1.getEffectiveGasPrice()).isNotEmpty(); + assertThat(tx1.getTo()).isEqualTo(expectedTx1.getTo().get().toString()); + assertThat(tx1.getType()) + .isEqualTo(String.format("0x%X", expectedTx1.getType().getEthSerializedType())); // Check TX2 receipt is correct TransactionReceiptResult tx2 = result.getResults().get(1); assertThat(tx2.getBlockNumber()).isEqualTo("0x1"); - assertThat(tx2.getEffectiveGasPrice()).isEqualTo("0xa6e00cb5"); - assertThat(tx2.getTo()).isEqualTo("0x429b96f49fb2e74ba0fda06cf6f380caffc2fac2"); - assertThat(tx2.getType()).isEqualTo("0x2"); + assertThat(tx2.getEffectiveGasPrice()).isNotEmpty(); + assertThat(tx2.getTo()).isEqualTo(expectedTx2.getTo().get().toString()); + assertThat(tx2.getType()) + .isEqualTo(String.format("0x%X", expectedTx2.getType().getEthSerializedType())); } @Test @@ -165,13 +182,6 @@ public void blockNotFoundWhenHash63CharsLong() { assertThat(actualResponse).usingRecursiveComparison().isEqualTo(blockNotFoundResponse); } - @Test - public void blockNotFoundForRandomHash() { - /* Valid random hash - should result in block not found (effectively impossible for it to be a valid block) */ - JsonRpcResponse actualResponse = method.response(requestWithParams(RANDOM_HASH)); - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(blockNotFoundResponse); - } - @Test public void blockNotFoundForZeroHash() { /* Zero hash - should result in block not found */ diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/encoding/TransactionAnnouncementEncoder.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/encoding/TransactionAnnouncementEncoder.java index dd7f14db928..ee55cc0de20 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/encoding/TransactionAnnouncementEncoder.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/encoding/TransactionAnnouncementEncoder.java @@ -81,7 +81,7 @@ private static Bytes encodeForEth68(final List transactions) { for (int i = 0; i < transactions.size(); i++) { final TransactionType type = transactions.get(i).getType(); - types[i] = type == TransactionType.FRONTIER ? 0x00 : type.getSerializedType(); + types[i] = type.getEthSerializedType(); sizes.add(transactions.get(i).getSize()); hashes.add(transactions.get(i).getHash()); } @@ -96,7 +96,7 @@ public static Bytes encodeForEth68( final byte[] byteTypes = new byte[types.size()]; for (int i = 0; i < types.size(); i++) { final TransactionType type = types.get(i); - byteTypes[i] = type == TransactionType.FRONTIER ? 0x00 : type.getSerializedType(); + byteTypes[i] = type.getEthSerializedType(); } return encodeForEth68(byteTypes, sizes, hashes); } From a355fcf0b17c26af1b652b19c2bb273355ce4ca9 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Wed, 23 Aug 2023 11:10:23 +0100 Subject: [PATCH 9/9] Add spec JSON/RPC tests Signed-off-by: Matthew Whitehead --- .../eth/eth_getBlockReceiptsByHash_00.json | 31 ++++++++++++++ .../eth_getBlockReceiptsByHash_NotFound.json | 19 +++++++++ .../eth/eth_getBlockReceiptsByNumber_1.json | 31 ++++++++++++++ .../eth/eth_getBlockReceiptsByNumber_32.json | 41 +++++++++++++++++++ ...eth_getBlockReceiptsByNumber_NotFound.json | 19 +++++++++ .../eth/eth_getBlockReceiptsByTag_latest.json | 41 +++++++++++++++++++ ...ockReceipts_invalidParams_blockNumber.json | 19 +++++++++ ...th_getBlockReceipts_invalidParams_tag.json | 19 +++++++++ 8 files changed, 220 insertions(+) create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByHash_00.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByHash_NotFound.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_1.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_32.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_NotFound.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByTag_latest.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_blockNumber.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_tag.json diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByHash_00.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByHash_00.json new file mode 100644 index 00000000000..a468a6af592 --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByHash_00.json @@ -0,0 +1,31 @@ +{ + "request": { + "id": 302, + "jsonrpc": "2.0", + "method": "eth_getBlockReceipts", + "params": [ + "0x1878c6f27178250f3d55186a2887b076936599f307d96dabcf331b2ff0a38f0c" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 302, + "result": [ { + "blockHash" : "0x1878c6f27178250f3d55186a2887b076936599f307d96dabcf331b2ff0a38f0c", + "blockNumber" : "0x10", + "contractAddress" : null, + "cumulativeGasUsed" : "0xab90", + "from" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "gasUsed" : "0xab90", + "effectiveGasPrice" : "0x1", + "logs" : [ ], + "logsBloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "root" : "0xed8541244d07552bed21ab19a7a26bc9f6ac0826d91c20fed11961a746270af0", + "to" : "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "transactionHash" : "0x9f6a5eb65991ce483a9e1bfc57b44cd2c8ff4c26ca804240d593b4b63c3eafcd", + "transactionIndex" : "0x0", + "type" : "0x0" + } ] + }, + "statusCode": 200 +} \ No newline at end of file diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByHash_NotFound.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByHash_NotFound.json new file mode 100644 index 00000000000..32d19394a48 --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByHash_NotFound.json @@ -0,0 +1,19 @@ +{ + "request": { + "id": 303, + "jsonrpc": "2.0", + "method": "eth_getBlockReceipts", + "params": [ + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 303, + "error" : { + "code" : -32000, + "message" : "Block not found" + } +}, +"statusCode": 200 +} \ No newline at end of file diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_1.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_1.json new file mode 100644 index 00000000000..2fb13be4b64 --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_1.json @@ -0,0 +1,31 @@ +{ + "request": { + "id": 304, + "jsonrpc": "2.0", + "method": "eth_getBlockReceipts", + "params": [ + "0x1" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 304, + "result": [ { + "blockHash" : "0x10aaf14a53caf27552325374429d3558398a36d3682ede6603c2c6511896e9f9", + "blockNumber" : "0x1", + "contractAddress" : "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "cumulativeGasUsed" : "0x78674", + "from" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "gasUsed" : "0x78674", + "effectiveGasPrice" : "0x1", + "logs" : [ ], + "logsBloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "root" : "0x6a59608add7cee26032d1c5c3923b91d0b50e6103f61b2137b68229bcdc87395", + "to" : null, + "transactionHash" : "0x812742182a79a8e67733edc58cfa3767aa2d7ad06439d156ddbbb33e3403b4ed", + "transactionIndex" : "0x0", + "type" : "0x0" + } ] + }, + "statusCode": 200 +} \ No newline at end of file diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_32.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_32.json new file mode 100644 index 00000000000..f67a4a37262 --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_32.json @@ -0,0 +1,41 @@ +{ + "request": { + "id": 305, + "jsonrpc": "2.0", + "method": "eth_getBlockReceipts", + "params": [ + "0x20" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 305, + "result": [ { + "blockHash" : "0x71d59849ddd98543bdfbe8548f5eed559b07b8aaf196369f39134500eab68e53", + "blockNumber" : "0x20", + "contractAddress" : null, + "cumulativeGasUsed" : "0x5c99", + "from" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "gasUsed" : "0x5c99", + "effectiveGasPrice" : "0x1", + "logs" : [ { + "address" : "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "topics" : [ "0x0000000000000000000000000000000000000000000000000000000000000001", "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ], + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9000000000000000000000000000000000000000000000000000000000000002a", + "blockNumber" : "0x20", + "transactionHash" : "0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310", + "transactionIndex" : "0x0", + "blockHash" : "0x71d59849ddd98543bdfbe8548f5eed559b07b8aaf196369f39134500eab68e53", + "logIndex" : "0x0", + "removed" : false + } ], + "logsBloom" : "0x00000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000080000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000400000000000000000200000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000800000000040000000000000000000000000000000000000000010000000000000000000000000", + "root" : "0x6d54fb51c667e4cc4bd8f2633b675f831b35d7784a70b5df91cd58f593c5286e", + "to" : "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "transactionHash" : "0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310", + "transactionIndex" : "0x0", + "type" : "0x0" + } ] + }, + "statusCode": 200 +} \ No newline at end of file diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_NotFound.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_NotFound.json new file mode 100644 index 00000000000..37453eadb42 --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByNumber_NotFound.json @@ -0,0 +1,19 @@ +{ + "request": { + "id": 306, + "jsonrpc": "2.0", + "method": "eth_getBlockReceipts", + "params": [ + "0x20202020202020" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 306, + "error" : { + "code" : -32000, + "message" : "Block not found" + } +}, +"statusCode": 200 +} \ No newline at end of file diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByTag_latest.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByTag_latest.json new file mode 100644 index 00000000000..229039240a5 --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceiptsByTag_latest.json @@ -0,0 +1,41 @@ +{ + "request": { + "id": 307, + "jsonrpc": "2.0", + "method": "eth_getBlockReceipts", + "params": [ + "latest" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 307, + "result": [ { + "blockHash" : "0x71d59849ddd98543bdfbe8548f5eed559b07b8aaf196369f39134500eab68e53", + "blockNumber" : "0x20", + "contractAddress" : null, + "cumulativeGasUsed" : "0x5c99", + "from" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "gasUsed" : "0x5c99", + "effectiveGasPrice" : "0x1", + "logs" : [ { + "address" : "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "topics" : [ "0x0000000000000000000000000000000000000000000000000000000000000001", "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ], + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9000000000000000000000000000000000000000000000000000000000000002a", + "blockNumber" : "0x20", + "transactionHash" : "0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310", + "transactionIndex" : "0x0", + "blockHash" : "0x71d59849ddd98543bdfbe8548f5eed559b07b8aaf196369f39134500eab68e53", + "logIndex" : "0x0", + "removed" : false + } ], + "logsBloom" : "0x00000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000080000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000400000000000000000200000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000800000000040000000000000000000000000000000000000000010000000000000000000000000", + "root" : "0x6d54fb51c667e4cc4bd8f2633b675f831b35d7784a70b5df91cd58f593c5286e", + "to" : "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "transactionHash" : "0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310", + "transactionIndex" : "0x0", + "type" : "0x0" + } ] + }, + "statusCode": 200 +} \ No newline at end of file diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_blockNumber.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_blockNumber.json new file mode 100644 index 00000000000..91f6a6af8f7 --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_blockNumber.json @@ -0,0 +1,19 @@ +{ + "request": { + "id": 300, + "jsonrpc": "2.0", + "method": "eth_getBlockReceipts", + "params": [ + "0x02020202020202020202020202" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 300, + "error" : { + "code" : -32602, + "message" : "Invalid params" + } + }, + "statusCode": 200 +} \ No newline at end of file diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_tag.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_tag.json new file mode 100644 index 00000000000..655ff6013ae --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_tag.json @@ -0,0 +1,19 @@ +{ + "request": { + "id": 301, + "jsonrpc": "2.0", + "method": "eth_getBlockReceipts", + "params": [ + "invalidtag" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 301, + "error" : { + "code" : -32602, + "message" : "Invalid params" + } + }, + "statusCode": 200 +} \ No newline at end of file