Skip to content
Merged
9 changes: 4 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
- Remove `--Xsnapsync-server-enabled` deprecated since 25.7.0. Use `--snapsync-server-enabled` instead.
- Remove `--Xsnapsync-synchronizer-pre-merge-headers-only-enabled` deprecated since 25.7.0. Use `--snapsync-synchronizer-pre-checkpoint-headers-only-enabled` instead.
- 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)
- RPC changes to enhance compatibility with other ELs
- 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)
- Remove PoW specific RPCs: `eth_getMinerDataByBlockHash`, `eth_getMinerDataByBlockNumber`, `miner_setCoinbase`, `miner_setEtherbase` [#9481](https://github.com/hyperledger/besu/pull/9481)

### Upcoming Breaking Changes
Expand All @@ -23,12 +25,9 @@
### Additions and Improvements
- Update to vertx 4.5.22 [#9375](https://github.com/hyperledger/besu/pull/9375)
- 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)
- Use Eclipse Temurin OpenJDK JRE in Besu docker image [#9392](https://github.com/hyperledger/besu/pull/9392)
- Performance: 5-6x faster toFastHex calculation for engine_getBlobsV2 [#9426](https://github.com/hyperledger/besu/pull/9426)
- Add Linea named networks for mainnet and sepolia on Linea network [#9436](https://github.com/hyperledger/besu/pull/9436)
- Remove PoW specific RPCs: `eth_getMinerDataByBlockHash`, `eth_getMinerDataByBlockNumber`, `miner_setCoinbase`, `miner_setEtherbase` [#9481](https://github.com/hyperledger/besu/pull/9481)

### Bug fixes
- Fix loss of colored output in terminal when using `--color-enabled=true` option [#8908](https://github.com/hyperledger/besu/issues/8908)
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?
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
}