Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPC methods that lookup block by hash will now return error if no block found #4582

Merged
merged 13 commits into from
Jan 9, 2023
Merged
8 changes: 5 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
## 23.1.0-beta2

### Breaking Changes
- Default configurations for the deprecated Ropsten, Kiln, Shandong, and Astor networks have been removed from the CLI network list. These networks can currently be accessed but will require a user-provided genesis configuration. [#4896](https://github.com/hyperledger/besu/pull/4869)
- Default configurations for the deprecated Ropsten, Kiln, Shandong, and Astor networks have been removed from the CLI network list. These networks can currently be accessed but will require a user-provided genesis configuration. [#4869](https://github.com/hyperledger/besu/pull/4869)

### Additions and Improvements
- RPC methods that lookup block by hash will now return an error response if no block found [#4582](https://github.com/hyperledger/besu/pull/4582)

### Bug Fixes

Expand Down Expand Up @@ -96,11 +97,12 @@ https://hyperledger.jfrog.io/hyperledger/besu-binaries/besu/22.10.1/besu-22.10.1
## 22.10.0

### Breaking Changes
- Internal and interface APIs relating to storage have migrated from `UInt256` to `Bytes32` [#4562](https://github.com/hyperledger/besu/pull/4562)
- Flexible Privacy Groups (early access) support to Tessera's EC encryptor (contracts modified) [#4282](https://github.com/hyperledger/besu/pull/4282)
* Before this change, the `bytes32` type was used for the enclave public keys, just supporting encryptors with public keys of that length (like the default NaCl)
* For the EC encryptor, the encoded public key length is 91
- `--tx-pool-hashes-max-size` option removed (deprecated in 22.1.3)
- `--Xmerge-support` option remove (deprecated in 22.4.2) [#4518](https://github.com/hyperledger/besu/pull/4518)
- `--Xmerge-support` option removed (deprecated in 22.4.2) [#4518](https://github.com/hyperledger/besu/pull/4518)
- Breaking API changes in the `OperationTracer` interface to enable performance work.
* The `traceExecution` method has been replaced with `tracePreExecution` and `tracePostExecution` methods, called just before and just after operation execution.
* See `DebugOperationTracer` and `StandardJsonTracer` for migration examples.
Expand Down Expand Up @@ -159,7 +161,7 @@ https://hyperledger.jfrog.io/hyperledger/besu-binaries/besu/22.10.0/besu-22.10.0
- Reduce the number of runtime exceptions (SecurityModuleException) and unnecessary executions during ECIES handshake, by trying to decrypt EIP-8 formatted messages first [#4508](https://github.com/hyperledger/besu/pull/4508).
- Improved RLP processing of zero-length string as 0x80 [#4283](https://github.com/hyperledger/besu/pull/4283) [#4388](https://github.com/hyperledger/besu/issues/4388)
- Increased level of detail in JSON-RPC parameter error log messages [#4510](https://github.com/hyperledger/besu/pull/4510)
- New unstable configuration options to set the maximum time, in milliseconds, a PoS block creation jobs is allowed to run [#4519](https://github.com/hyperledger/besu/pull/4519)
- New experimental configuration options to set the maximum time, in milliseconds, a PoS block creation jobs is allowed to run [#4519](https://github.com/hyperledger/besu/pull/4519)
- Tune EthScheduler thread pools to avoid recreating too many threads [#4529](https://github.com/hyperledger/besu/pull/4529)
- RocksDB snapshot based worldstate and plugin-api addition of Snapshot interfaces [#4409](https://github.com/hyperledger/besu/pull/4409)
- Continuously try to build better block proposals until timeout or GetPayload is called [#4516](https://github.com/hyperledger/besu/pull/4516)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
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.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.BlockHeader;

import java.util.Optional;
import java.util.OptionalLong;
Expand Down Expand Up @@ -95,6 +96,14 @@ protected Object handleParamTypes(final JsonRpcRequestContext requestContext) {
requestContext.getRequest().getId(), JsonRpcError.INVALID_PARAMS);
}

// return error if block hash does not find a block
Optional<BlockHeader> maybeBlockHeader =
getBlockchainQueries().getBlockHeaderByHash(blockHash.get());
if (maybeBlockHeader.isEmpty()) {
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), JsonRpcError.BLOCK_NOT_FOUND);
}

if (Boolean.TRUE.equals(blockParameterOrBlockHash.getRequireCanonical())
&& !getBlockchainQueries().blockIsOnCanonicalChain(blockHash.get())) {
return new JsonRpcErrorResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.evm.account.Account;
Expand All @@ -55,6 +56,7 @@ class DebugAccountAtTest {
@Mock private BlockTracer blockTracer;
@Mock private BlockchainQueries blockchainQueries;
@Mock private BlockWithMetadata<TransactionWithMetadata, Hash> blockWithMetadata;
@Mock private BlockHeader blockHeader;
@Mock private TransactionWithMetadata transactionWithMetadata;
@Mock private BlockTrace blockTrace;
@Mock private TransactionTrace transactionTrace;
Expand All @@ -77,7 +79,7 @@ void nameShouldBeDebugAccountAt() {

@Test
void testBlockNotFoundResponse() {
Mockito.when(blockchainQueries.blockByHash(any())).thenReturn(Optional.empty());
Mockito.when(blockchainQueries.getBlockHeaderByHash(any())).thenReturn(Optional.empty());

final Object[] params = new Object[] {Hash.ZERO.toHexString(), 0, Address.ZERO.toHexString()};
final JsonRpcRequestContext request =
Expand All @@ -91,7 +93,7 @@ void testBlockNotFoundResponse() {

@Test
void testInvalidParamsResponseEmptyList() {
Mockito.when(blockchainQueries.blockByHash(any())).thenReturn(Optional.of(blockWithMetadata));
setupMockBlock();
Mockito.when(blockWithMetadata.getTransactions()).thenReturn(Collections.emptyList());

final Object[] params = new Object[] {Hash.ZERO.toHexString(), 0, Address.ZERO.toHexString()};
Expand All @@ -106,7 +108,7 @@ void testInvalidParamsResponseEmptyList() {

@Test
void testInvalidParamsResponseNegative() {
Mockito.when(blockchainQueries.blockByHash(any())).thenReturn(Optional.of(blockWithMetadata));
setupMockBlock();
Mockito.when(blockWithMetadata.getTransactions())
.thenReturn(Collections.singletonList(transactionWithMetadata));

Expand All @@ -122,7 +124,7 @@ void testInvalidParamsResponseNegative() {

@Test
void testInvalidParamsResponseTooHigh() {
Mockito.when(blockchainQueries.blockByHash(any())).thenReturn(Optional.of(blockWithMetadata));
setupMockBlock();
Mockito.when(blockWithMetadata.getTransactions())
.thenReturn(Collections.singletonList(transactionWithMetadata));

Expand All @@ -138,7 +140,7 @@ void testInvalidParamsResponseTooHigh() {

@Test
void testTransactionNotFoundResponse() {
Mockito.when(blockchainQueries.blockByHash(any())).thenReturn(Optional.of(blockWithMetadata));
setupMockBlock();
Mockito.when(blockWithMetadata.getTransactions())
.thenReturn(Collections.singletonList(transactionWithMetadata));

Expand All @@ -155,6 +157,7 @@ void testTransactionNotFoundResponse() {
@Test
void testNoAccountFoundResponse() {
setupMockTransaction();
setupMockBlock();

final Object[] params = new Object[] {Hash.ZERO.toHexString(), 0, Address.ZERO.toHexString()};
final JsonRpcRequestContext request =
Expand All @@ -179,6 +182,7 @@ void shouldBeSuccessfulWhenTransactionsAndAccountArePresent() {

setupMockTransaction();
setupMockAccount();
setupMockBlock();

Mockito.when(account.getCode()).thenReturn(code);
Mockito.when(account.getNonce()).thenReturn(nonce);
Expand Down Expand Up @@ -217,4 +221,10 @@ private void setupMockTransaction() {
Mockito.when(transactionWithMetadata.getTransaction()).thenReturn(transaction);
Mockito.when(transaction.getHash()).thenReturn(Hash.ZERO);
}

private void setupMockBlock() {
Mockito.when(blockchainQueries.blockByHash(any())).thenReturn(Optional.of(blockWithMetadata));
Mockito.when(blockchainQueries.getBlockHeaderByHash(any()))
.thenReturn(Optional.of(blockHeader));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"request": {
"id": 250,
"jsonrpc": "2.0",
"method": "eth_getCode",
"params": [
"0x8888f1f195afa192cfee860698584c030f4c9db1",
"0xe4ba271c3580fafebd874dc3107eba505b1061fd8d9780e3a5577e48f6168711"
]
},
"response": {
"jsonrpc": "2.0",
"id": 250,
"error" : {
"code" : -32000,
"message" : "Block not found"
}
},
"statusCode": 200
}