Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Remove `--Xhistory-expiry-prune` deprecated since 25.7.0. Use `--history-expiry-prune` instead.
- Use error code 3 for execution reverted [#9365](https://github.com/hyperledger/besu/pull/9365)
- eth_createAccessList now returns success result if execution reverted [#9358](https://github.com/hyperledger/besu/pull/9358)
- Return null result if block not found for `debug_accountAt`, `debug_setHead`, `eth_call`, `eth_getBlockReceipts`, `eth_getProof`, `eth_simulateV1`, `eth_getBalance`, `eth_getCode`, `eth_getStorageAt`, `eth_getTransactionCount` [#9303](https://github.com/hyperledger/besu/pull/9303)

### Upcoming Breaking Changes
- Sunsetting features - for more context on the reasoning behind the deprecation of these features, including alternative options, read [this blog post](https://www.lfdecentralizedtrust.org/blog/sunsetting-tessera-and-simplifying-hyperledger-besu)
Expand All @@ -22,6 +23,7 @@
- Add `opcodes` optional parameter to RPC methods: `debug_standardTraceBlockToFile`, `debug_standardTraceBadBlockToFile`, `debug_traceBlockByNumber`, `debug_traceBlockByHash`, `debug_traceTransaction`, `debug_traceBlock`, `debug_traceCall` for tracing specified opcodes [#9335](https://github.com/hyperledger/besu/pull/9335)
- Use error code 3 for execution reverted [#9365](https://github.com/hyperledger/besu/pull/9365)
- eth_createAccessList now returns success result if execution reverted [#9358](https://github.com/hyperledger/besu/pull/9358)
- Return null result if block not found for `debug_accountAt`, `debug_setHead`, `eth_call`, `eth_getBlockReceipts`, `eth_getProof`, `eth_simulateV1`, `eth_getBalance`, `eth_getCode`, `eth_getStorageAt`, `eth_getTransactionCount` [#9303](https://github.com/hyperledger/besu/pull/9303)
- Use Eclipse Temurin OpenJDK JRE in Besu docker image [#9392](https://github.com/hyperledger/besu/pull/9392)

### Bug fixes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,12 @@ protected Object handleParamTypes(final JsonRpcRequestContext requestContext) {
} else if (blockParameterOrBlockHash.isNumeric() || blockParameterOrBlockHash.isEarliest()) {
final OptionalLong blockNumber = blockParameterOrBlockHash.getNumber();
if (blockNumber.isEmpty() || blockNumber.getAsLong() < 0) {
// TODO should this be null result or invalid params?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not clear on this either even after going through #9197. Looks like some clients return an error and some a null response. Think we should just leave this as is returning an error until we know otherwise.

return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS);
} else if (blockNumber.getAsLong() > getBlockchainQueries().headBlockNumber()) {
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), RpcErrorType.BLOCK_NOT_FOUND);
// return null if a future block is requested
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), null);
}

result =
Expand All @@ -122,19 +123,17 @@ protected Object handleParamTypes(final JsonRpcRequestContext requestContext) {
} else {
Optional<Hash> blockHash = blockParameterOrBlockHash.getHash();
if (blockHash.isEmpty()) {
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_HASH_PARAMS);
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), null);
}

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

if (Boolean.TRUE.equals(blockParameterOrBlockHash.getRequireCanonical())
if (blockParameterOrBlockHash.getRequireCanonical()
&& !getBlockchainQueries().blockIsOnCanonicalChain(blockHash.get())) {
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), RpcErrorType.JSON_RPC_NOT_CANONICAL_ERROR);
Expand All @@ -150,7 +149,7 @@ protected Object handleParamTypes(final JsonRpcRequestContext requestContext) {
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
Object response = handleParamTypes(requestContext);

if (response instanceof JsonRpcErrorResponse) {
if (response instanceof JsonRpcResponse) {
return (JsonRpcResponse) response;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,16 @@ void nameShouldBeDebugAccountAt() {
}

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

final Object[] params = new Object[] {Hash.ZERO.toHexString(), 0, Address.ZERO.toHexString()};
final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("2.0", "debug_accountAt", params));
final JsonRpcResponse response = debugAccountAt.response(request);

Assertions.assertThat(response).isInstanceOf(JsonRpcErrorResponse.class);
Assertions.assertThat(((JsonRpcErrorResponse) response).getErrorType())
.isEqualByComparingTo(RpcErrorType.BLOCK_NOT_FOUND);
Assertions.assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class);
Assertions.assertThat(((JsonRpcSuccessResponse) response).getResult()).isNull();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
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.parameters.BlockParameterOrBlockHash;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
Expand Down Expand Up @@ -146,21 +147,26 @@ public void assertBothChainHeadAndWorldStatByNumber(final String blockParam) {
}

@Test
public void assertNotFound() {
public void assertNullWhenBlockNotFound() {
var chainTip = blockchain.getChainHead().getBlockHeader();

// move the head to number just after chain head
var resp =
debugSetHead.response(debugSetHead("" + chainTip.getNumber() + 1, Optional.of(TRUE)));
assertThat(resp.getType()).isEqualTo(RpcResponseType.ERROR);
// success with null result if block not found
assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS);
assertThat(((JsonRpcSuccessResponse) resp).getResult()).isNull();

// move the head to some arbitrary hash
var resp2 =
debugSetHead.response(
debugSetHead(
Hash.keccak256(Bytes.fromHexString("0xdeadbeef")).toHexString(),
Optional.of(TRUE)));
assertThat(resp2.getType()).isEqualTo(RpcResponseType.ERROR);

// success with null result if block not found
assertThat(resp2.getType()).isEqualTo(RpcResponseType.SUCCESS);
assertThat(((JsonRpcSuccessResponse) resp2).getResult()).isNull();

// get the new chainTip:
var newChainTip = blockchain.getChainHead().getBlockHeader();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.BLOCK_NOT_FOUND;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INTERNAL_ERROR;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.REVERT_ERROR;
import static org.mockito.ArgumentMatchers.any;
Expand Down Expand Up @@ -64,6 +63,7 @@
import java.util.OptionalLong;

import org.apache.tuweni.bytes.Bytes;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -486,13 +486,14 @@ public void shouldUseCorrectBlockNumberWhenSpecified() {
}

@Test
public void shouldReturnBlockNotFoundWhenInvalidBlockNumberSpecified() {
public void shouldReturnNullWhenInvalidBlockNumberSpecified() {
final JsonRpcRequestContext request = ethCallRequest(callParameter(), Quantity.create(33L));
when(blockchainQueries.headBlockNumber()).thenReturn(14L);
final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, BLOCK_NOT_FOUND);

final JsonRpcResponse response = method.response(request);
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);

Assertions.assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class);
Assertions.assertThat(((JsonRpcSuccessResponse) response).getResult()).isNull();

verify(blockchainQueries).headBlockNumber();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@
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.jsonrpc.internal.results.TransactionReceiptResult;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
Expand Down Expand Up @@ -65,8 +63,7 @@ public class EthGetBlockReceiptsTest {
private static final BlockDataGenerator blockDataGenerator = new BlockDataGenerator();
private EthGetBlockReceipts method;
private ProtocolSchedule protocolSchedule;
final JsonRpcResponse blockNotFoundResponse =
new JsonRpcErrorResponse(null, RpcErrorType.BLOCK_NOT_FOUND);
final JsonRpcResponse blockNotFoundResponse = new JsonRpcSuccessResponse(null, null);

@BeforeEach
public void setUp() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@
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.proof.GetProofResult;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
Expand Down Expand Up @@ -121,20 +120,18 @@ void errorWhenNoBlockNumberSupplied() {
}

@Test
void errorWhenWorldStateUnavailable() {

final JsonRpcErrorResponse expectedResponse =
new JsonRpcErrorResponse(null, RpcErrorType.BLOCK_NOT_FOUND);
void shouldReturnNullWhenWorldStateUnavailable() {

final JsonRpcRequestContext request =
requestWithParams(
Address.fromHexString("0x0000000000000000000000000000000000000000"),
new String[] {storageKey.toString()},
String.valueOf(501));

final JsonRpcErrorResponse response = (JsonRpcErrorResponse) method.response(request);
final JsonRpcResponse response = method.response(request);

assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
Assertions.assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class);
Assertions.assertThat(((JsonRpcSuccessResponse) response).getResult()).isNull();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.BLOCK_NOT_FOUND;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.hyperledger.besu.ethereum.api.ApiConfiguration;
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.parameters.SimulateV1Parameter;
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.results.Quantity;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
Expand All @@ -35,6 +34,7 @@
import java.util.List;
import java.util.Optional;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -76,14 +76,16 @@ public void shouldReturnCorrectMethodName() {
}

@Test
public void shouldReturnBlockNotFoundWhenInvalidBlockNumberSpecified() {
public void shouldReturnNullWhenInvalidBlockNumberSpecified() {
final JsonRpcRequestContext request =
ethSimulateV1Request(simulateParameter(), Quantity.create(33L));
when(blockchainQueries.headBlockNumber()).thenReturn(14L);
final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, BLOCK_NOT_FOUND);

final JsonRpcResponse response = method.response(request);
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);

Assertions.assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class);
Assertions.assertThat(((JsonRpcSuccessResponse) response).getResult()).isNull();

verify(blockchainQueries).headBlockNumber();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
"response": {
"jsonrpc": "2.0",
"id": 28,
"error": {
"code": -32000,
"message": "Block not found"
}
"result": null
},
"statusCode": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@
]
},
"response": {
"jsonrpc": "2.0",
"id": 303,
"error" : {
"code" : -32000,
"message" : "Block not found"
}
},
"jsonrpc": "2.0",
"id": 303,
"result": null
},
"statusCode": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@
]
},
"response": {
"jsonrpc": "2.0",
"id": 306,
"error" : {
"code" : -32000,
"message" : "Block not found"
}
},
"jsonrpc": "2.0",
"id": 306,
"result": null
},
"statusCode": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
"response": {
"jsonrpc": "2.0",
"id": 250,
"error" : {
"code" : -32000,
"message" : "Block not found"
}
"result": null
},
"statusCode": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
"response": {
"jsonrpc": "2.0",
"id": 13,
"error": {
"code": -32000,
"message": "Block not found"
}
"result": null
},
"statusCode": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
"response": {
"jsonrpc": "2.0",
"id": 28,
"error": {
"code": -32000,
"message": "Block not found"
}
"result": null
},
"statusCode": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
"response": {
"jsonrpc": "2.0",
"id": 337,
"error": {
"code": -32000,
"message": "Block not found"
}
"result": null
},
"statusCode": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
"response": {
"jsonrpc": "2.0",
"id": 487,
"error": {
"code": -32000,
"message": "Block not found"
}
"result": null
},
"statusCode": 200
}