From 8523ed0e438b186638d97cca89c6f7b63ccbeadb Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 16 Aug 2024 15:46:56 +1000 Subject: [PATCH 1/7] 5098 branch 21 update more invalid params (#7467) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_HASH_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_COUNT Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Add index to exception messages Signed-off-by: Matilda Clerke * 5098: apoply spotless Signed-off-by: Matilda Clerke * 5098: Update BaseJsonRpcProcessor to utilise RpcErrorType from InvalidJsonRpcParameters Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Rename INVALID_AUTH_PARAMS to INVALID_PROPOSAL_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update INVALID_BLOCK_HASH_PARAMS locations Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_INDEX Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_NUMBER Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CALL_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CONSOLIDATION_REQUEST_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CREATE_PRIVACY_GROUP_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken test Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_DATA_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_DEPOSIT_REQUEST_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PAYLOAD_ATTRIBUTES_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PAYLOAD_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENODE_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_EXTRA_DATA_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_FILTER_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Update several RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Hopefully fix broken integration test Signed-off-by: Matilda Clerke * 5098: Hopefully fix broken integration test Signed-off-by: Matilda Clerke * 5098: Update several more RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_PARAM_COUNT Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_PAYLOAD_ID_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_PENDING_TRANSACTIONS_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVAlID_PLUGIN_NAME_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Update RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * Update ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java Co-authored-by: Sally MacFarlane Signed-off-by: Matilda-Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../internal/methods/EthFeeHistory.java | 11 ++- .../jsonrpc/internal/methods/EthGetProof.java | 11 ++- .../internal/methods/EthGetStorageAt.java | 8 +- .../internal/methods/EthSubmitHashRate.java | 10 ++- .../internal/methods/EthSubmitWork.java | 8 +- .../engine/EngineExchangeCapabilities.java | 15 +++- .../privacy/methods/PrivGetFilterChanges.java | 10 ++- .../privacy/methods/PrivGetFilterLogs.java | 10 ++- .../privacy/methods/PrivUninstallFilter.java | 12 ++- .../privacy/methods/priv/PrivCall.java | 10 ++- .../methods/priv/PrivDebugGetStateRoot.java | 12 ++- .../methods/priv/PrivDeletePrivacyGroup.java | 12 ++- .../privacy/methods/priv/PrivGetCode.java | 10 ++- .../priv/PrivGetEeaTransactionCount.java | 16 +++- .../privacy/methods/priv/PrivGetLogs.java | 10 ++- .../methods/priv/PrivGetTransactionCount.java | 10 ++- .../privacy/methods/priv/PrivNewFilter.java | 10 ++- .../request/SubscriptionRequestMapper.java | 75 ++++++++++++++++--- .../api/jsonrpc/JsonRpcHttpServiceTest.java | 2 +- .../internal/methods/EthGetProofTest.java | 2 +- .../privacy/methods/priv/PrivCallTest.java | 3 +- .../priv/PrivDebugGetStateRootTest.java | 3 +- .../priv/PrivGetFilterChangesTest.java | 2 +- .../methods/priv/PrivGetFilterLogsTest.java | 2 +- .../privacy/methods/priv/PrivGetLogsTest.java | 2 +- .../methods/priv/PrivNewFilterTest.java | 2 +- .../methods/priv/PrivUninstallFilterTest.java | 4 +- .../SubscriptionRequestMapperTest.java | 6 +- .../ethereum/stratum/StratumProtocol.java | 8 +- 29 files changed, 244 insertions(+), 52 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java index e2056ac94b5..01a08022790 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java @@ -106,8 +106,15 @@ public JsonRpcResponse response(final JsonRpcRequestContext request) { "Invalid highest block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } - final Optional> maybeRewardPercentiles = - request.getOptionalParameter(2, Double[].class).map(Arrays::asList); + final Optional> maybeRewardPercentiles; + try { + maybeRewardPercentiles = request.getOptionalParameter(2, Double[].class).map(Arrays::asList); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid reward percentiles parameter (index 2)", + RpcErrorType.INVALID_REWARD_PERCENTILES_PARAMS, + e); + } final BlockHeader chainHeadHeader = blockchain.getChainHeadHeader(); final long chainHeadBlockNumber = chainHeadHeader.getNumber(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java index a20cd62f290..7c2f67b724f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java @@ -106,8 +106,13 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } private List getStorageKeys(final JsonRpcRequestContext request) { - return Arrays.stream(request.getRequiredParameter(1, String[].class)) - .map(UInt256::fromHexString) - .collect(Collectors.toList()); + try { + return Arrays.stream(request.getRequiredParameter(1, String[].class)) + .map(UInt256::fromHexString) + .collect(Collectors.toList()); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid storage keys parameters (index 1)", RpcErrorType.INVALID_STORAGE_KEYS_PARAMS, e); + } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java index 7b84365b561..34ed62b6329 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java @@ -56,7 +56,13 @@ protected String resultByBlockHash(final JsonRpcRequestContext request, final Ha throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final UInt256 position = request.getRequiredParameter(1, UInt256Parameter.class).getValue(); + final UInt256 position; + try { + position = request.getRequiredParameter(1, UInt256Parameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid position parameter (index 1)", RpcErrorType.INVALID_POSITION_PARAMS, e); + } return blockchainQueries .get() .storageAt(address, position, blockHash) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java index 9db7edcc804..c0763e77f6d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java @@ -42,11 +42,17 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final String hashRate; try { hashRate = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( "Invalid hash rate parameter (index 0)", RpcErrorType.INVALID_HASH_RATE_PARAMS, e); } - final String id = requestContext.getRequiredParameter(1, String.class); + final String id; + try { + id = requestContext.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid sealer ID parameter (index 1)", RpcErrorType.INVALID_SEALER_ID_PARAMS, e); + } return new JsonRpcSuccessResponse( requestContext.getRequest().getId(), miningCoordinator.submitHashRate( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java index cebb2e7a006..9474fec7bad 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java @@ -65,7 +65,13 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid mix hash parameter (index 2)", RpcErrorType.INVALID_MIX_HASH_PARAMS, e); } - Bytes powHash = Bytes.fromHexString(requestContext.getRequiredParameter(1, String.class)); + Bytes powHash; + try { + powHash = Bytes.fromHexString(requestContext.getRequiredParameter(1, String.class)); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid PoW hash parameter (index 1)", RpcErrorType.INVALID_POW_HASH_PARAMS, e); + } final PoWSolution solution = new PoWSolution(nonce, mixHash, null, powHash); final boolean result = miner.submitWork(solution); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), result); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java index 0431898c78e..624d9bebddc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java @@ -20,9 +20,11 @@ import org.hyperledger.besu.ethereum.ProtocolContext; 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; 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 java.util.List; import java.util.stream.Collectors; @@ -55,7 +57,18 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) LOG.atTrace() .setMessage("received remote capabilities: {}") - .addArgument(() -> requestContext.getRequiredParameter(0, String[].class)) + .addArgument( + () -> { + try { + return requestContext.getRequiredParameter(0, String[].class); + } catch ( + Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid remote capabilities parameters (index 0)", + RpcErrorType.INVALID_REMOTE_CAPABILITIES_PARAMS, + e); + } + }) .log(); final List localCapabilities = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java index 7b9a8d1478f..bbd7189ffa3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java @@ -52,7 +52,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String filterId; try { filterId = requestContext.getRequiredParameter(1, String.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java index 0e564772c05..4436c33b502 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java @@ -52,7 +52,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String filterId; try { filterId = request.getRequiredParameter(1, String.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java index 738c0b19cf8..c1e122578ab 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java @@ -47,13 +47,21 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String filterId; try { filterId = request.getRequiredParameter(1, String.class); } catch (Exception e) { throw new InvalidJsonRpcParameters( - "Invalid filter ID paramter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); + "Invalid filter ID parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); } if (privacyController instanceof MultiTenancyPrivacyController) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java index 0418fc24746..e09d5966cf5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java @@ -65,7 +65,15 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { protected Object resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { final JsonCallParameter callParams = validateAndGetCallParams(request); - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String privacyUserId = privacyIdProvider.getPrivacyUserId(request.getUser()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java index b6ea645dc3e..9ee5d57b3b4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java @@ -72,7 +72,15 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { @Override protected Object resultByBlockNumber( final JsonRpcRequestContext requestContext, final long blockNumber) { - final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String privacyUserId = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); if (LOG.isTraceEnabled()) { LOG.trace("Executing {}", getName()); @@ -97,7 +105,7 @@ protected Object resultByBlockNumber( } } catch (final Exception e) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS); } if (privacyGroup.isEmpty()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java index db0c11ea5af..5c6f929c5c2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java @@ -18,11 +18,13 @@ 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; 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.privacy.MultiTenancyValidationException; import org.hyperledger.besu.ethereum.privacy.PrivacyController; @@ -50,7 +52,15 @@ public String getName() { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("Executing {}", RpcMethod.PRIV_DELETE_PRIVACY_GROUP.getMethodName()); - final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String response; try { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java index 0010b8e0525..5d9498f3bd4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java @@ -59,7 +59,15 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { @Override protected String resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final Address address; try { address = request.getRequiredParameter(1, Address.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java index 8fa43b79e37..7bdba8824a2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java @@ -73,8 +73,20 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final String privateFrom = requestContext.getRequiredParameter(1, String.class); - final String[] privateFor = requestContext.getRequiredParameter(2, String[].class); + final String privateFrom; + try { + privateFrom = requestContext.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid private from parameter (index 1)", RpcErrorType.INVALID_PRIVATE_FROM_PARAMS, e); + } + final String[] privateFor; + try { + privateFor = requestContext.getRequiredParameter(2, String[].class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid private for parameter (index 2)", RpcErrorType.INVALID_PRIVATE_FOR_PARAMS, e); + } final String privacyUserId = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java index abb6411b00c..d0c75da33fb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java @@ -62,7 +62,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final FilterParameter filter; try { filter = requestContext.getRequiredParameter(1, FilterParameter.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java index b51f0fc36fe..2cbcc655359 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java @@ -64,7 +64,15 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final String privacyGroupId = requestContext.getRequiredParameter(1, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 1)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } try { final long nonce = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java index f9a080c72f4..e73b0c141c6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java @@ -50,7 +50,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final FilterParameter filter; try { filter = request.getRequiredParameter(1, FilterParameter.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java index d9099e697dc..7235a81987a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java @@ -32,8 +32,15 @@ public SubscribeRequest mapSubscribeRequest(final JsonRpcRequestContext jsonRpcR try { final WebSocketRpcRequest webSocketRpcRequestBody = validateRequest(jsonRpcRequestContext); - final SubscriptionType subscriptionType = - webSocketRpcRequestBody.getRequiredParameter(0, SubscriptionType.class); + final SubscriptionType subscriptionType; + try { + subscriptionType = webSocketRpcRequestBody.getRequiredParameter(0, SubscriptionType.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription type parameter (index 0)", + RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, + e); + } switch (subscriptionType) { case NEW_BLOCK_HEADERS: { @@ -60,8 +67,13 @@ public SubscribeRequest mapSubscribeRequest(final JsonRpcRequestContext jsonRpcR } private boolean includeTransactions(final WebSocketRpcRequest webSocketRpcRequestBody) { - final Optional params = - webSocketRpcRequestBody.getOptionalParameter(1, SubscriptionParam.class); + final Optional params; + try { + params = webSocketRpcRequestBody.getOptionalParameter(1, SubscriptionParam.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription parameter (index 1)", RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, e); + } return params.isPresent() && params.get().includeTransaction(); } @@ -88,8 +100,16 @@ public UnsubscribeRequest mapUnsubscribeRequest(final JsonRpcRequestContext json try { final WebSocketRpcRequest webSocketRpcRequestBody = validateRequest(jsonRpcRequestContext); - final long subscriptionId = - webSocketRpcRequestBody.getRequiredParameter(0, UnsignedLongParameter.class).getValue(); + final long subscriptionId; + try { + subscriptionId = + webSocketRpcRequestBody.getRequiredParameter(0, UnsignedLongParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription ID parameter (index 0)", + RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, + e); + } return new UnsubscribeRequest(subscriptionId, webSocketRpcRequestBody.getConnectionId()); } catch (final Exception e) { throw new InvalidSubscriptionRequestException("Error parsing unsubscribe request", e); @@ -102,9 +122,24 @@ public PrivateSubscribeRequest mapPrivateSubscribeRequest( try { final WebSocketRpcRequest webSocketRpcRequestBody = validateRequest(jsonRpcRequestContext); - final String privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); - final SubscriptionType subscriptionType = - webSocketRpcRequestBody.getRequiredParameter(1, SubscriptionType.class); + final String privacyGroupId; + try { + privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } + final SubscriptionType subscriptionType; + try { + subscriptionType = webSocketRpcRequestBody.getRequiredParameter(1, SubscriptionType.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription type parameter (index 1)", + RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, + e); + } switch (subscriptionType) { case LOGS: @@ -142,9 +177,25 @@ public PrivateUnsubscribeRequest mapPrivateUnsubscribeRequest( try { final WebSocketRpcRequest webSocketRpcRequestBody = validateRequest(jsonRpcRequestContext); - final String privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); - final long subscriptionId = - webSocketRpcRequestBody.getRequiredParameter(1, UnsignedLongParameter.class).getValue(); + final String privacyGroupId; + try { + privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } + final long subscriptionId; + try { + subscriptionId = + webSocketRpcRequestBody.getRequiredParameter(1, UnsignedLongParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription ID parameter (index 1)", + RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, + e); + } return new PrivateUnsubscribeRequest( subscriptionId, webSocketRpcRequestBody.getConnectionId(), privacyGroupId); } catch (final Exception e) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index 7be6b7499ef..dcfd198d6e1 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -2033,7 +2033,7 @@ public void ethGetStorageAtInvalidParameterStorageIndex() throws Exception { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_POSITION_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java index 3cf24df3d45..06a4b9d0e7c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java @@ -120,7 +120,7 @@ void errorWhenNoStorageKeysSupplied() { Assertions.assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 1"); + .hasMessageContaining("Invalid storage keys parameters (index 1)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java index 0919ea48e92..cc5169d75d5 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java @@ -173,8 +173,7 @@ public void shouldThrowCorrectExceptionWhenNoPrivacyGroupSpecified() { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasNoCause() - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid privacy group ID parameter (index 0)"); } private JsonCallParameter callParameter() { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java index a7a4f6f5906..c730be1db85 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java @@ -82,8 +82,7 @@ public void shouldThrowInvalidJsonRpcParametersExceptionWhenNoPrivacyGroup() { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasNoCause() - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java index cf89a4bbcad..3b9f5c81314 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java @@ -81,7 +81,7 @@ public void privacyGroupIdIsRequired() { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java index 1c5be875722..c055988271f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java @@ -75,7 +75,7 @@ public void privacyGroupIdIsRequired() { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java index d06b47ee103..9426f214786 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java @@ -87,7 +87,7 @@ public void privacyGroupIdIsRequired() { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java index 696e3333cad..855da64b011 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java @@ -78,7 +78,7 @@ public void privacyGroupIdIsRequired() { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java index 9a60d60d725..74935692e8d 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java @@ -61,7 +61,7 @@ public void privacyGroupIdIsRequired() { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test @@ -70,7 +70,7 @@ public void filterIdIsRequired() { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid filter ID paramter (index 1)"); + .hasMessageContaining("Invalid filter ID parameter (index 1)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java index 80bb9b05dcc..f560dfaa089 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java @@ -83,7 +83,7 @@ public void mapRequestToUnsubscribeRequestMissingSubscriptionIdFails() { .isInstanceOf(InvalidSubscriptionRequestException.class) .getCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid subscription type parameter (index 0)"); } @Test @@ -138,7 +138,7 @@ public void mapRequestToNewHeadsWithInvalidSecondParamFails() { .isInstanceOf(InvalidSubscriptionRequestException.class) .getCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid subscription parameter (index 1)"); } @Test @@ -372,7 +372,7 @@ public void mapAbsentSubscriptionTypeRequestFails() { .isInstanceOf(InvalidSubscriptionRequestException.class) .getCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid subscription type parameter (index 0)"); } @Test diff --git a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java index 7f928fbddad..3f13a568803 100644 --- a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java +++ b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java @@ -87,7 +87,13 @@ default void handleHashrateSubmit( throw new InvalidJsonRpcParameters( "Invalid hash rate parameter (index 0)", RpcErrorType.INVALID_HASH_RATE_PARAMS, e); } - final String id = message.getRequiredParameter(1, String.class); + final String id; + try { + id = message.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid sealer ID parameter (index 1)", RpcErrorType.INVALID_SEALER_ID_PARAMS, e); + } String response; try { response = From dff99f7c17a87a45467e65a570941da9477848cb Mon Sep 17 00:00:00 2001 From: Karim Taam Date: Fri, 16 Aug 2024 13:58:24 +0100 Subject: [PATCH 2/7] Implement getNearest methods (#7258) Signed-off-by: Karim Taam --- plugin-api/build.gradle | 2 +- .../storage/SegmentedKeyValueStorage.java | 34 +- .../RocksDBColumnarKeyValueSnapshot.java | 13 +- .../RocksDBColumnarKeyValueStorage.java | 15 +- .../rocksdb/NearestKeyValueStorageTest.java | 336 ++++++++++++++++++ .../besu/services/kvstore/KeyComparator.java | 61 ++++ .../kvstore/LayeredKeyValueStorage.java | 71 +++- .../SegmentedInMemoryKeyValueStorage.java | 73 +++- .../AbstractSegmentedKeyValueStorageTest.java | 81 ----- .../kvstore/InMemoryKeyValueStorageTest.java | 31 -- .../services/kvstore/KeyComparatorTest.java | 63 ++++ .../kvstore/LayeredKeyValueStorageTest.java | 32 -- 12 files changed, 634 insertions(+), 178 deletions(-) create mode 100644 plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/NearestKeyValueStorageTest.java create mode 100644 services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/KeyComparator.java delete mode 100644 services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/AbstractSegmentedKeyValueStorageTest.java delete mode 100644 services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/InMemoryKeyValueStorageTest.java create mode 100644 services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/KeyComparatorTest.java delete mode 100644 services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorageTest.java diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index fe7308993b8..4440a4f0691 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,7 @@ Calculated : ${currentHash} tasks.register('checkAPIChanges', FileStateChecker) { description = "Checks that the API for the Plugin-API project does not change without deliberate thought" files = sourceSets.main.allJava.files - knownHash = 'W1gv5UjqU+RJZJN6xPNjVfjuz7nKIcBgmh1j2XON4EU=' + knownHash = '6Hy3eaCpnxehyDO3smSAr1i2DsB2q/V37/m8POycikI=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/storage/SegmentedKeyValueStorage.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/storage/SegmentedKeyValueStorage.java index df8a8c48941..4f734c7c977 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/storage/SegmentedKeyValueStorage.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/storage/SegmentedKeyValueStorage.java @@ -39,15 +39,35 @@ public interface SegmentedKeyValueStorage extends Closeable { Optional get(SegmentIdentifier segment, byte[] key) throws StorageException; /** - * Find the key and corresponding value "nearest to" the specified key. Nearest is defined as - * either matching the supplied key or the key lexicographically prior to it. + * Finds the key and corresponding value that is "nearest before" the specified key. "Nearest + * before" is defined as the closest key that is either exactly matching the supplied key or + * lexicographically before it. * - * @param segmentIdentifier segment to scan - * @param key key for which we are searching for the nearest match. - * @return Optional of NearestKeyValue-wrapped matched key and corresponding value. - * @throws StorageException the storage exception + * @param segmentIdentifier The segment to scan for the nearest key. + * @param key The key for which we are searching for the nearest match before it. + * @return An Optional of NearestKeyValue, wrapping the matched key and its corresponding value, + * if found. + * @throws StorageException If an error occurs during the retrieval process. + */ + Optional getNearestBefore(final SegmentIdentifier segmentIdentifier, Bytes key) + throws StorageException; + + /** + * Finds the key and corresponding value that is "nearest after" the specified key. "Nearest + * after" is defined as the closest key that is either exactly matching the supplied key or + * lexicographically after it. + * + *

This method aims to find the next key in sequence after the provided key, considering the + * order of keys within the specified segment. It is particularly useful for iterating over keys + * in a sorted manner starting from a given key. + * + * @param segmentIdentifier The segment to scan for the nearest key. + * @param key The key for which we are searching for the nearest match after it. + * @return An Optional of NearestKeyValue, wrapping the matched key and its corresponding value, + * if found. + * @throws StorageException If an error occurs during the retrieval process. */ - Optional getNearestTo(final SegmentIdentifier segmentIdentifier, Bytes key) + Optional getNearestAfter(final SegmentIdentifier segmentIdentifier, Bytes key) throws StorageException; /** diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueSnapshot.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueSnapshot.java index dfc1c8a1ac5..72976a9d84b 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueSnapshot.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueSnapshot.java @@ -76,7 +76,7 @@ public Optional get(final SegmentIdentifier segment, final byte[] key) } @Override - public Optional getNearestTo( + public Optional getNearestBefore( final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { try (final RocksIterator rocksIterator = snapTx.getIterator(segmentIdentifier)) { @@ -87,6 +87,17 @@ public Optional getNearestTo( } } + @Override + public Optional getNearestAfter( + final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + try (final RocksIterator rocksIterator = snapTx.getIterator(segmentIdentifier)) { + rocksIterator.seek(key.toArrayUnsafe()); + return Optional.of(rocksIterator) + .filter(AbstractRocksIterator::isValid) + .map(it -> new NearestKeyValue(Bytes.of(it.key()), Optional.of(it.value()))); + } + } + @Override public Stream> stream(final SegmentIdentifier segment) { throwIfClosed(); diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorage.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorage.java index 647dc7019f7..0bf107ddb0e 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorage.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorage.java @@ -354,7 +354,7 @@ public Optional get(final SegmentIdentifier segment, final byte[] key) } @Override - public Optional getNearestTo( + public Optional getNearestBefore( final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { try (final RocksIterator rocksIterator = @@ -366,6 +366,19 @@ public Optional getNearestTo( } } + @Override + public Optional getNearestAfter( + final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + + try (final RocksIterator rocksIterator = + getDB().newIterator(safeColumnHandle(segmentIdentifier))) { + rocksIterator.seek(key.toArrayUnsafe()); + return Optional.of(rocksIterator) + .filter(AbstractRocksIterator::isValid) + .map(it -> new NearestKeyValue(Bytes.of(it.key()), Optional.of(it.value()))); + } + } + @Override public Stream> stream(final SegmentIdentifier segmentIdentifier) { final RocksIterator rocksIterator = getDB().newIterator(safeColumnHandle(segmentIdentifier)); diff --git a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/NearestKeyValueStorageTest.java b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/NearestKeyValueStorageTest.java new file mode 100644 index 00000000000..54cd03215fc --- /dev/null +++ b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/NearestKeyValueStorageTest.java @@ -0,0 +1,336 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * 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.plugin.services.storage.rocksdb; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.BesuConfiguration; +import org.hyperledger.besu.plugin.services.storage.DataStorageConfiguration; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; +import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage.NearestKeyValue; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction; +import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration; +import org.hyperledger.besu.services.kvstore.LayeredKeyValueStorage; +import org.hyperledger.besu.services.kvstore.SegmentedInMemoryKeyValueStorage; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.IntStream; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class NearestKeyValueStorageTest { + + @TempDir private static Path tempDir; + + private static RocksDBKeyValueStorageFactory rocksdbStorageFactory; + private static BesuConfiguration commonConfiguration; + + @BeforeAll + public static void setup() throws IOException { + rocksdbStorageFactory = + new RocksDBKeyValueStorageFactory( + () -> + new RocksDBFactoryConfiguration( + DEFAULT_MAX_OPEN_FILES, + DEFAULT_BACKGROUND_THREAD_COUNT, + DEFAULT_CACHE_CAPACITY, + DEFAULT_IS_HIGH_SPEC), + Arrays.asList(KeyValueSegmentIdentifier.values()), + RocksDBMetricsFactory.PUBLIC_ROCKS_DB_METRICS); + + Utils.createDatabaseMetadataV2(tempDir, DataStorageFormat.BONSAI, 2); + + mockCommonConfiguration(tempDir); + } + + @Test + public void testNearestRocksdbWithInMemoryKeyValueStorage() { + final SegmentedKeyValueStorage rockdDBKeyValueStorage = + getRocksDBKeyValueStorage(TRIE_BRANCH_STORAGE); + final SegmentedKeyValueStorageTransaction rocksDbTransaction = + rockdDBKeyValueStorage.startTransaction(); + + final SegmentedKeyValueStorage inMemoryDBKeyValueStorage = getInMemoryDBKeyValueStorage(); + final SegmentedKeyValueStorageTransaction inMemoryDBTransaction = + inMemoryDBKeyValueStorage.startTransaction(); + IntStream.range(1, 10) + .forEach( + i -> { + final byte[] key = Bytes.fromHexString("0x000" + i).toArrayUnsafe(); + final byte[] value = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key, value); + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key, value); + // different common prefix, and reversed order of bytes: + final byte[] key2 = Bytes.fromHexString("0x010" + (10 - i)).toArrayUnsafe(); + final byte[] value2 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + // different size: + final byte[] key3 = Bytes.fromHexString("0x01011" + (10 - i)).toArrayUnsafe(); + final byte[] value3 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + final byte[] key4 = Bytes.fromHexString("0x0" + (10 - i)).toArrayUnsafe(); + final byte[] value4 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + }); + rocksDbTransaction.commit(); + inMemoryDBTransaction.commit(); + + // compare rocksdb implementation with inmemory implementation + rockdDBKeyValueStorage.stream(TRIE_BRANCH_STORAGE) + .forEach( + pair -> { + final Bytes key = Bytes.of(pair.getKey()); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, key), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, key))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, key), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, key))) + .isTrue(); + + final Bytes biggerKey = Bytes.concatenate(key, Bytes.of(0x01)); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, biggerKey), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, biggerKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, biggerKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, biggerKey))) + .isTrue(); + + final Bytes smallerKey = key.slice(0, key.size() - 1); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, smallerKey), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, smallerKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestAfter( + TRIE_BRANCH_STORAGE, smallerKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, smallerKey))) + .isTrue(); + + final Bytes reversedKey = key.reverse(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, reversedKey), + rockdDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, reversedKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestAfter( + TRIE_BRANCH_STORAGE, reversedKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, reversedKey))) + .isTrue(); + }); + } + + @Test + public void testNearestRocksdbWithLayeredKeyValueStorage() { + final SegmentedKeyValueStorage rockdDBKeyValueStorage = + getRocksDBKeyValueStorage(TRIE_BRANCH_STORAGE); + final SegmentedKeyValueStorageTransaction rocksDbTransaction = + rockdDBKeyValueStorage.startTransaction(); + + final SegmentedKeyValueStorage inMemoryDBKeyValueStorage = getInMemoryDBKeyValueStorage(); + final SegmentedKeyValueStorageTransaction inMemoryDBTransaction = + inMemoryDBKeyValueStorage.startTransaction(); + + final LayeredKeyValueStorage layeredDBKeyValueStorage = + new LayeredKeyValueStorage(inMemoryDBKeyValueStorage); + final SegmentedKeyValueStorageTransaction layeredDBTransaction = + layeredDBKeyValueStorage.startTransaction(); + + IntStream.range(1, 10) + .forEach( + i -> { + final byte[] key = Bytes.fromHexString("0x000" + i).toArrayUnsafe(); + final byte[] value = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key, value); + // as we have several layers I store sometimes in the child layer and sometimes in the + // parent + if (i % 2 == 0) { + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key, value); + } else { + layeredDBTransaction.put(TRIE_BRANCH_STORAGE, key, value); + } + // different common prefix, and reversed order of bytes: + final byte[] key2 = Bytes.fromHexString("0x010" + (10 - i)).toArrayUnsafe(); + final byte[] value2 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + // as we have several layers I store sometimes in the child layer and sometimes in the + // parent + if (i % 2 == 0) { + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + } else { + layeredDBTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + } + // different size: + final byte[] key3 = Bytes.fromHexString("0x01011" + (10 - i)).toArrayUnsafe(); + final byte[] value3 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + // as we have several layers I store sometimes in the child layer and sometimes in the + // parent + if (i % 2 == 0) { + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + } else { + layeredDBTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + } + final byte[] key4 = Bytes.fromHexString("0x0" + (10 - i)).toArrayUnsafe(); + final byte[] value4 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + // as we have several layers I store sometimes in the child layer and sometimes in the + // parent + if (i % 2 == 0) { + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + } else { + layeredDBTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + } + }); + rocksDbTransaction.commit(); + inMemoryDBTransaction.commit(); + layeredDBTransaction.commit(); + + // compare rocksdb implementation with inmemory implementation + rockdDBKeyValueStorage.stream(TRIE_BRANCH_STORAGE) + .forEach( + pair -> { + final Bytes key = Bytes.of(pair.getKey()); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, key), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, key))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, key), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, key))) + .isTrue(); + + final Bytes biggerKey = Bytes.concatenate(key, Bytes.of(0x01)); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, biggerKey), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, biggerKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, biggerKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, biggerKey))) + .isTrue(); + + final Bytes smallerKey = key.slice(0, key.size() - 1); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, smallerKey), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, smallerKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, smallerKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, smallerKey))) + .isTrue(); + + final Bytes reversedKey = key.reverse(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, reversedKey), + rockdDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, reversedKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestAfter( + TRIE_BRANCH_STORAGE, reversedKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, reversedKey))) + .isTrue(); + }); + } + + private SegmentedKeyValueStorage getRocksDBKeyValueStorage(final SegmentIdentifier segment) { + return rocksdbStorageFactory.create( + List.of(segment), commonConfiguration, new NoOpMetricsSystem()); + } + + private SegmentedKeyValueStorage getInMemoryDBKeyValueStorage() { + return new SegmentedInMemoryKeyValueStorage(); + } + + private static void mockCommonConfiguration(final Path tempDataDir) { + commonConfiguration = mock(BesuConfiguration.class); + when(commonConfiguration.getStoragePath()).thenReturn(tempDataDir); + when(commonConfiguration.getDataPath()).thenReturn(tempDataDir); + DataStorageConfiguration dataStorageConfiguration = mock(DataStorageConfiguration.class); + when(dataStorageConfiguration.getDatabaseFormat()).thenReturn(DataStorageFormat.BONSAI); + lenient() + .when(commonConfiguration.getDataStorageConfiguration()) + .thenReturn(dataStorageConfiguration); + } + + private boolean isNearestKeyValueTheSame( + final Optional v1, final Optional v2) { + if (v1.isPresent() && v2.isPresent()) { + final NearestKeyValue nearestKeyValue1 = v1.get(); + final NearestKeyValue nearestKeyValue2 = v2.get(); + if (nearestKeyValue1.key().equals(nearestKeyValue2.key())) { + if (nearestKeyValue1.value().isPresent() && nearestKeyValue2.value().isPresent()) { + return Arrays.equals(nearestKeyValue1.value().get(), nearestKeyValue2.value().get()); + } + } else if (nearestKeyValue1.value().isEmpty() && nearestKeyValue2.value().isEmpty()) { + return true; + } + } else if (v1.isEmpty() && v2.isEmpty()) { + return true; + } + return false; + } +} diff --git a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/KeyComparator.java b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/KeyComparator.java new file mode 100644 index 00000000000..ff9dd00dd8a --- /dev/null +++ b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/KeyComparator.java @@ -0,0 +1,61 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * 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.services.kvstore; + +import org.apache.tuweni.bytes.Bytes; + +/** + * This class is a comparator that allows comparing two byte arrays from left to right. + * + *

For example: + * + *

>0x01 is smaller than 0x0101 or 0x01 is smaller than 0x02. + */ +public class KeyComparator { + + /** Instantiates a new KeyComparator */ + public KeyComparator() {} + + /** + * Compares two keys from left to right. + * + *

This method performs a byte-by-byte comparison between two keys, starting from the left + * (most significant byte). It is designed to compare keys in a way that reflects their + * hierarchical or sequential order. + * + *

The method returns: - A negative integer if {@code key1} is lexicographically less than + * key2. - Zero if key1 and key2 are equal. - A positive integer if key1 is lexicographically + * greater than key2. + * + *

If the keys are of unequal length but identical for the length of the shorter key (prefix), + * the shorter key is considered to be lexicographically less than the longer key. This is + * consistent with the lexicographic ordering used by rocksdb. + * + * @param key1 the first key compare. + * @param key2 the second key to compare with. + * @return the value 0 if key1 is equal to key2; a value less than 0 if key1 is lexicographically + * less than key2; and a value greater than 0 if key1 is lexicographically greater than key2. + */ + public static int compareKeyLeftToRight(final Bytes key1, final Bytes key2) { + int minLength = Math.min(key1.size(), key2.size()); + for (int i = 0; i < minLength; i++) { + int compare = Byte.compareUnsigned(key1.get(i), key2.get(i)); + if (compare != 0) { + return compare; + } + } + return Integer.compare(key1.size(), key2.size()); + } +} diff --git a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java index 36bb5c52d8d..de9abcaf298 100644 --- a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java +++ b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java @@ -33,6 +33,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.locks.Lock; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -101,25 +102,77 @@ public Optional get(final SegmentIdentifier segmentId, final byte[] key) } @Override - public Optional getNearestTo( + public Optional getNearestBefore( final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { - Optional ourNearest = super.getNearestTo(segmentIdentifier, key); - Optional parentNearest = parent.getNearestTo(segmentIdentifier, key); + return getNearest( + key, + k -> super.getNearestBefore(segmentIdentifier, k), + k -> parent.getNearestBefore(segmentIdentifier, k), + false); + } + + @Override + public Optional getNearestAfter( + final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + return getNearest( + key, + k -> super.getNearestAfter(segmentIdentifier, k), + k -> parent.getNearestAfter(segmentIdentifier, k), + true); + } + + private Optional getNearest( + final Bytes key, + final Function> ourNearestFunction, + final Function> parentNearestFunction, + final boolean isAfter) + throws StorageException { + + final Optional ourNearest = ourNearestFunction.apply(key); + final Optional parentNearest = parentNearestFunction.apply(key); if (ourNearest.isPresent() && parentNearest.isPresent()) { - // Both are present, return the one closer to the key - int ourDistance = ourNearest.get().key().commonPrefixLength(key); - int parentDistance = parentNearest.get().key().commonPrefixLength(key); - return (ourDistance <= parentDistance) ? ourNearest : parentNearest; + return compareNearest(ourNearest, parentNearest, key, isAfter); } else if (ourNearest.isPresent()) { - // Only ourNearest is present return ourNearest; } else { - // return parentNearest, which may be an empty Optional return parentNearest; } } + private Optional compareNearest( + final Optional ourNearest, + final Optional parentNearest, + final Bytes key, + final boolean isAfter) { + + final int ourDistance = ourNearest.get().key().compareTo(key); + final int parentDistance = parentNearest.get().key().compareTo(key); + if (ourDistance == 0) { + return ourNearest; + } else if (parentDistance == 0) { + return parentNearest; + } else { + final int ourCommonPrefixLength = ourNearest.get().key().commonPrefixLength(key); + final int parentCommonPrefixLength = parentNearest.get().key().commonPrefixLength(key); + if (ourCommonPrefixLength != parentCommonPrefixLength) { + return ourCommonPrefixLength > parentCommonPrefixLength ? ourNearest : parentNearest; + } else { + // When searching for a key, if isAfter is true, we choose the next smallest key after our + // target because both found keys are after it. + // If isAfter is false, meaning we're doing a seekForPrev, we select the largest key that + // comes before our target, as it's the nearest one. + // For example : if the searched key is 0x0101 and we found 0x0001 and 0x0100 when isAfter + // == false we will take 0x0100 + if (ourNearest.get().key().compareTo(parentNearest.get().key()) > 0) { + return isAfter ? parentNearest : ourNearest; + } else { + return isAfter ? ourNearest : parentNearest; + } + } + } + } + @Override public Stream> stream(final SegmentIdentifier segmentId) { throwIfClosed(); diff --git a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/SegmentedInMemoryKeyValueStorage.java b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/SegmentedInMemoryKeyValueStorage.java index beabb04d84f..a7cedca362b 100644 --- a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/SegmentedInMemoryKeyValueStorage.java +++ b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/SegmentedInMemoryKeyValueStorage.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.services.kvstore; import static java.util.stream.Collectors.toUnmodifiableSet; +import static org.hyperledger.besu.services.kvstore.KeyComparator.compareKeyLeftToRight; import org.hyperledger.besu.plugin.services.exception.StorageException; import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier; @@ -39,6 +40,7 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -143,26 +145,67 @@ public Optional get(final SegmentIdentifier segmentIdentifier, final byt } @Override - public Optional getNearestTo( + public Optional getNearestBefore( final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + return getNearest( + segmentIdentifier, + e -> + compareKeyLeftToRight(e.getKey(), key) <= 0 + && e.getKey().commonPrefixLength(key) >= e.getKey().size(), + e -> compareKeyLeftToRight(e.getKey(), key) < 0, + false); + } + + @Override + public Optional getNearestAfter( + final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + return getNearest( + segmentIdentifier, + e -> + compareKeyLeftToRight(e.getKey(), key) >= 0 + && e.getKey().commonPrefixLength(key) >= e.getKey().size(), + e -> compareKeyLeftToRight(e.getKey(), key) >= 0, + true); + } + + private Optional getNearest( + final SegmentIdentifier segmentIdentifier, + final Predicate>> samePrefixPredicate, + final Predicate>> fallbackPredicate, + final boolean useMin) + throws StorageException { final Lock lock = rwLock.readLock(); lock.lock(); try { - // TODO: revisit this for sort performance - Comparator>> comparing = - Comparator.comparing( - (Map.Entry> a) -> a.getKey().commonPrefixLength(key)) - .thenComparing(Map.Entry.comparingByKey()); - return this.hashValueStore - .computeIfAbsent(segmentIdentifier, s -> newSegmentMap()) - .entrySet() - .stream() - // only return keys equal to or less than - .filter(e -> e.getKey().compareTo(key) <= 0) - .sorted(comparing.reversed()) - .findFirst() - .map(z -> new NearestKeyValue(z.getKey(), z.getValue())); + final Map> segmentMap = + this.hashValueStore.computeIfAbsent(segmentIdentifier, s -> newSegmentMap()); + + final Function>>, Optional> + findNearest = + (predicate) -> { + final Stream>> filteredStream = + segmentMap.entrySet().stream().filter(predicate); + // Depending on the useMin flag, find either the minimum or maximum entry according + // to key order + final Optional>> sortedStream = + useMin + ? filteredStream.min( + (t1, t2) -> compareKeyLeftToRight(t1.getKey(), t2.getKey())) + : filteredStream.max( + (t1, t2) -> compareKeyLeftToRight(t1.getKey(), t2.getKey())); + return sortedStream.map( + entry -> new NearestKeyValue(entry.getKey(), entry.getValue())); + }; + + // First, attempt to find a key-value pair that matches the same prefix + final Optional withSamePrefix = findNearest.apply(samePrefixPredicate); + if (withSamePrefix.isPresent()) { + return withSamePrefix; + } + // If a matching entry with a common prefix is not found, the next step is to search for the + // nearest key that comes after or before the requested one. + return findNearest.apply(fallbackPredicate); } finally { lock.unlock(); } diff --git a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/AbstractSegmentedKeyValueStorageTest.java b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/AbstractSegmentedKeyValueStorageTest.java deleted file mode 100644 index f96cc90157a..00000000000 --- a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/AbstractSegmentedKeyValueStorageTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright contributors to Hyperledger Besu. - * - * 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.services.kvstore; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage.SEGMENT_IDENTIFIER; - -import org.hyperledger.besu.kvstore.AbstractKeyValueStorageTest; -import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; -import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction; - -import java.util.stream.IntStream; - -import org.apache.tuweni.bytes.Bytes; -import org.junit.jupiter.api.Test; - -public abstract class AbstractSegmentedKeyValueStorageTest extends AbstractKeyValueStorageTest { - public abstract SegmentedKeyValueStorage createSegmentedStore(); - - @Test - public void assertSegmentedIsNearestTo() throws Exception { - try (final var store = this.createSegmentedStore()) { - - // create 10 entries - final SegmentedKeyValueStorageTransaction tx = store.startTransaction(); - IntStream.range(1, 10) - .forEach( - i -> { - final byte[] key = bytesFromHexString("000" + i); - final byte[] value = bytesFromHexString("0FFF"); - tx.put(SEGMENT_IDENTIFIER, key, value); - // different common prefix, and reversed order of bytes: - final byte[] key2 = bytesFromHexString("010" + (10 - i)); - final byte[] value2 = bytesFromHexString("0FFF"); - tx.put(SEGMENT_IDENTIFIER, key2, value2); - }); - tx.commit(); - - // assert 0009 is closest to 000F - var val = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("000F")); - assertThat(val).isPresent(); - assertThat(val.get().key()).isEqualTo(Bytes.fromHexString("0009")); - - // assert 0109 is closest to 010D - var val2 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("010D")); - assertThat(val2).isPresent(); - assertThat(val2.get().key()).isEqualTo(Bytes.fromHexString("0109")); - - // assert 0103 is closest to 0103 - var val3 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("0103")); - assertThat(val3).isPresent(); - assertThat(val3.get().key()).isEqualTo(Bytes.fromHexString("0103")); - - // assert 0003 is closest to 0003 - var val4 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("0003")); - assertThat(val4).isPresent(); - assertThat(val4.get().key()).isEqualTo(Bytes.fromHexString("0003")); - - // assert 0001 is closest to 0001 - var val5 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("0001")); - assertThat(val5).isPresent(); - assertThat(val5.get().key()).isEqualTo(Bytes.fromHexString("0001")); - - // assert 0000 is not present - var val6 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("0000")); - assertThat(val6).isNotPresent(); - } - } -} diff --git a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/InMemoryKeyValueStorageTest.java b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/InMemoryKeyValueStorageTest.java deleted file mode 100644 index 55a10ffa8d1..00000000000 --- a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/InMemoryKeyValueStorageTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.services.kvstore; - -import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; -import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; - -public class InMemoryKeyValueStorageTest extends AbstractSegmentedKeyValueStorageTest { - - @Override - protected KeyValueStorage createStore() { - return new InMemoryKeyValueStorage(); - } - - @Override - public SegmentedKeyValueStorage createSegmentedStore() { - return new SegmentedInMemoryKeyValueStorage(); - } -} diff --git a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/KeyComparatorTest.java b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/KeyComparatorTest.java new file mode 100644 index 00000000000..b6f536f8b6c --- /dev/null +++ b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/KeyComparatorTest.java @@ -0,0 +1,63 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * 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.services.kvstore; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; + +public class KeyComparatorTest { + + @Test + public void testEmptyVs01() { + Bytes key1 = Bytes.EMPTY; + Bytes key2 = Bytes.fromHexString("0x01"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "Empty key should be considered smaller than 0x01"); + } + + @Test + public void test01Vs02() { + Bytes key1 = Bytes.fromHexString("0x01"); + Bytes key2 = Bytes.fromHexString("0x02"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "0x01 should be considered smaller than 0x02"); + } + + @Test + public void test01Vs0100() { + Bytes key1 = Bytes.fromHexString("0x01"); + Bytes key2 = Bytes.fromHexString("0x0100"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "0x01 should be considered smaller than 0x0100"); + } + + @Test + public void test01Vs0201() { + Bytes key1 = Bytes.fromHexString("0x01"); + Bytes key2 = Bytes.fromHexString("0x0201"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "0x01 should be considered smaller than 0x0201"); + } + + @Test + public void test0101Vs02() { + Bytes key1 = Bytes.fromHexString("0x0101"); + Bytes key2 = Bytes.fromHexString("0x02"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "0x0101 should be considered smaller than 0x02"); + } +} diff --git a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorageTest.java b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorageTest.java deleted file mode 100644 index dba0ae2a366..00000000000 --- a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorageTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright contributors to Hyperledger Besu. - * - * 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.services.kvstore; - -import static org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage.SEGMENT_IDENTIFIER; - -import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; -import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; - -public class LayeredKeyValueStorageTest extends AbstractSegmentedKeyValueStorageTest { - @Override - protected KeyValueStorage createStore() { - return new SegmentedKeyValueStorageAdapter(SEGMENT_IDENTIFIER, createSegmentedStore()); - } - - @Override - public SegmentedKeyValueStorage createSegmentedStore() { - return new LayeredKeyValueStorage(new SegmentedInMemoryKeyValueStorage()); - } -} From 12576d77058f170fc3afbddf39e296c7e6302760 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 16 Aug 2024 22:06:53 +0200 Subject: [PATCH 3/7] Correctly release txpool save and restore lock in case of exceptions (#7473) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../besu/ethereum/eth/transactions/TransactionPool.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 183ca24e550..84641ea16e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Fix protocol schedule check for devnets [#7429](https://github.com/hyperledger/besu/pull/7429) - Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431) - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) +- Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) ## 24.7.1 diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java index c069a771eb2..6bb2029960a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java @@ -706,7 +706,8 @@ private CompletableFuture serializeAndDedupOperation( isCancelled.set(false); operationInProgress.set( - CompletableFuture.runAsync(operation).thenRun(diskAccessLock::release)); + CompletableFuture.runAsync(operation) + .whenComplete((res, err) -> diskAccessLock.release())); return operationInProgress.get(); } else { CompletableFuture.failedFuture( From f50f7c09d8ce0ef146067743df49ce3b5d39cb39 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Fri, 16 Aug 2024 17:03:07 -0700 Subject: [PATCH 4/7] Bump changelog ahead of 24.8.0 (#7476) * bump changelog Signed-off-by: garyschulte --- CHANGELOG.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84641ea16e1..9173e46fd5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ ## Next release +### Upcoming Breaking Changes + +### Breaking Changes + +### Additions and Improvements +- Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) + +### Bug fixes +- Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) +- Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) + +## 24.8.0 + ### Upcoming Breaking Changes - Receipt compaction will be enabled by default in a future version of Besu. After this change it will not be possible to downgrade to the previous Besu version. - --Xbonsai-limit-trie-logs-enabled is deprecated, use --bonsai-limit-trie-logs-enabled instead @@ -18,15 +31,12 @@ - Added support for tracing private transactions using `priv_traceTransaction` API. [#6161](https://github.com/hyperledger/besu/pull/6161) - Wrap WorldUpdater into EVMWorldupdater [#7434](https://github.com/hyperledger/besu/pull/7434) - Bump besu-native to 0.9.4 [#7456](https://github.com/hyperledger/besu/pull/7456) -- Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) ### Bug fixes - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) - Fix protocol schedule check for devnets [#7429](https://github.com/hyperledger/besu/pull/7429) - Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431) -- Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) -- Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) ## 24.7.1 From ef8aa7c9ecfddd01f5d8511877c5084ee7e673bb Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 19 Aug 2024 11:35:58 +1000 Subject: [PATCH 5/7] 5098 branch 22 update more invalid params (#7472) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../methods/IbftProposeValidatorVote.java | 8 ++++- .../methods/IbftProposeValidatorVoteTest.java | 4 +-- .../methods/QbftProposeValidatorVote.java | 8 ++++- .../methods/QbftProposeValidatorVoteTest.java | 4 +-- .../internal/methods/DebugAccountAt.java | 12 ++++++-- .../methods/DebugGetRawTransaction.java | 12 +++++++- .../DebugStandardTraceBadBlockToFile.java | 11 +++++-- .../DebugStandardTraceBlockToFile.java | 11 +++++-- .../internal/methods/DebugStorageRangeAt.java | 18 +++++++++-- .../internal/methods/DebugTraceBlock.java | 18 +++++++---- .../methods/DebugTraceBlockByHash.java | 18 +++++++---- .../methods/DebugTraceBlockByNumber.java | 18 +++++++---- .../internal/methods/DebugTraceCall.java | 15 +++++++--- .../methods/DebugTraceTransaction.java | 30 +++++++++++++++---- .../EthGetTransactionByBlockHashAndIndex.java | 22 ++++++++++++-- ...thGetTransactionByBlockNumberAndIndex.java | 10 ++++++- .../methods/EthGetTransactionByHash.java | 11 ++++++- .../methods/EthGetTransactionReceipt.java | 12 +++++++- .../methods/EthSendRawTransaction.java | 9 +++++- .../jsonrpc/internal/methods/TraceCall.java | 9 +++++- .../internal/methods/TraceCallMany.java | 2 +- .../jsonrpc/internal/methods/TraceGet.java | 21 +++++++++++-- .../internal/methods/TraceRawTransaction.java | 20 ++++++++++--- .../methods/TraceReplayBlockTransactions.java | 9 ++++-- .../internal/methods/TraceTransaction.java | 12 +++++++- .../TxPoolBesuPendingTransactions.java | 12 ++++++-- .../AbstractEngineForkchoiceUpdated.java | 2 +- .../engine/AbstractEngineNewPayload.java | 24 ++++++++------- .../methods/engine/EngineNewPayloadV3.java | 2 +- .../methods/engine/EngineNewPayloadV4.java | 2 +- .../miner/MinerChangeTargetGasLimit.java | 8 ++++- .../parameters/TraceTypeParameter.java | 5 +++- .../eea/AbstractEeaSendRawTransaction.java | 9 +++++- .../priv/PrivDistributeRawTransaction.java | 11 ++++++- .../priv/PrivGetEeaTransactionCount.java | 2 +- .../priv/PrivGetPrivateTransaction.java | 12 +++++++- .../priv/PrivGetTransactionReceipt.java | 11 ++++++- .../api/util/DomainObjectDecodeUtils.java | 7 +++-- .../internal/methods/DebugAccountAtTest.java | 6 ++-- .../AbstractEngineForkchoiceUpdatedTest.java | 2 +- .../engine/EngineForkchoiceUpdatedV1Test.java | 2 +- .../engine/EngineForkchoiceUpdatedV2Test.java | 2 +- .../miner/MinerChangeTargetGasLimitTest.java | 3 +- .../eea/EeaSendRawTransactionTest.java | 6 ++-- ...actionByBlockHashAndIndex_intOverflow.json | 2 +- ...onByBlockHashAndIndex_missingParam_00.json | 2 +- ...onByBlockHashAndIndex_missingParam_01.json | 2 +- ...tionByBlockHashAndIndex_missingParams.json | 2 +- ...ionByBlockHashAndIndex_wrongParamType.json | 2 +- ...eth_getTransactionByHash_typeMismatch.json | 2 +- ...BlockTransactions_invalidTraceOptions.json | 2 +- .../retesteth/methods/TestGetLogHash.java | 12 +++++++- .../methods/TestModifyTimestamp.java | 10 ++++++- 53 files changed, 388 insertions(+), 100 deletions(-) diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java index a29187b5138..9364422c578 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java @@ -60,7 +60,13 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final Boolean add = requestContext.getRequiredParameter(1, Boolean.class); + final Boolean add; + try { + add = requestContext.getRequiredParameter(1, Boolean.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid vote type parameter (index 1)", RpcErrorType.INVALID_VOTE_TYPE_PARAMS, e); + } LOG.trace( "Received RPC rpcName={} voteType={} address={}", getName(), diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java index d0df723d54f..dfa6f7b6e59 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java @@ -63,7 +63,7 @@ public void exceptionWhenNoParamsSupplied() { public void exceptionWhenNoAuthSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(Address.fromHexString("1")))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 1"); + .hasMessage("Invalid vote type parameter (index 1)"); } @Test @@ -77,7 +77,7 @@ public void exceptionWhenNoAddressSupplied() { public void exceptionWhenInvalidBoolParameterSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(Address.fromHexString("1"), "c"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid vote type parameter (index 1)"); } @Test diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java index 9eefbb8d13a..aa3a8b267e5 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java @@ -60,7 +60,13 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final Boolean add = requestContext.getRequiredParameter(1, Boolean.class); + final Boolean add; + try { + add = requestContext.getRequiredParameter(1, Boolean.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid vote type parameter (index 1)", RpcErrorType.INVALID_VOTE_TYPE_PARAMS, e); + } LOG.trace( "Received RPC rpcName={} voteType={} address={}", getName(), diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java index 62f7dc61691..1f5b1466d97 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java @@ -65,7 +65,7 @@ public void exceptionWhenNoParamsSupplied() { public void exceptionWhenNoAuthSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(Address.fromHexString("1")))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 1"); + .hasMessage("Invalid vote type parameter (index 1)"); } @Test @@ -79,7 +79,7 @@ public void exceptionWhenNoAddressSupplied() { public void exceptionWhenInvalidBoolParameterSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(Address.fromHexString("1"), "c"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid vote type parameter (index 1)"); } @Test diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java index 550a25982d2..602f3de3e0c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java @@ -78,7 +78,15 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( @Override protected Object resultByBlockHash( final JsonRpcRequestContext requestContext, final Hash blockHash) { - final Integer txIndex = requestContext.getRequiredParameter(1, Integer.class); + final Integer txIndex; + try { + txIndex = requestContext.getRequiredParameter(1, Integer.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction index parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_INDEX_PARAMS, + e); + } final Address address; try { address = requestContext.getRequiredParameter(2, Address.class); @@ -97,7 +105,7 @@ protected Object resultByBlockHash( List transactions = block.get().getTransactions(); if (transactions.isEmpty() || txIndex < 0 || txIndex > block.get().getTransactions().size()) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_TRANSACTION_PARAMS); } return Tracer.processTracing( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java index ab1230ca961..d6ede25b27e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java @@ -17,8 +17,10 @@ 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.exception.InvalidJsonRpcParameters; 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.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; @@ -38,7 +40,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash txHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash txHash; + try { + txHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } return blockchainQueries .transactionByHash(txHash) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java index 7587e40c75a..2d0c4cac4e2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java @@ -60,8 +60,15 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } - final Optional transactionTraceParams = - requestContext.getOptionalParameter(1, TransactionTraceParams.class); + final Optional transactionTraceParams; + try { + transactionTraceParams = requestContext.getOptionalParameter(1, TransactionTraceParams.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameters (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } final BadBlockManager badBlockManager = protocolContext.getBadBlockManager(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java index 601eabeab14..5fba2911bdd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java @@ -67,8 +67,15 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } - final Optional transactionTraceParams = - requestContext.getOptionalParameter(1, TransactionTraceParams.class); + final Optional transactionTraceParams; + try { + transactionTraceParams = requestContext.getOptionalParameter(1, TransactionTraceParams.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameters (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } return blockchainQueries .get() diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java index f6f16013318..5aabff4b574 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java @@ -77,7 +77,15 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } - final int transactionIndex = requestContext.getRequiredParameter(1, Integer.class); + final int transactionIndex; + try { + transactionIndex = requestContext.getRequiredParameter(1, Integer.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction index parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_INDEX_PARAMS, + e); + } final Address accountAddress; try { accountAddress = requestContext.getRequiredParameter(2, Address.class); @@ -92,7 +100,13 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid data start hash parameter (index 3)", RpcErrorType.INVALID_DATA_HASH_PARAMS, e); } - final int limit = requestContext.getRequiredParameter(4, Integer.class); + final int limit; + try { + limit = requestContext.getRequiredParameter(4, Integer.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid limit parameter (index 4)", RpcErrorType.INVALID_TRANSACTION_LIMIT_PARAMS, e); + } final Optional blockHashOptional = hashFromParameter(blockParameterOrBlockHash); if (blockHashOptional.isEmpty()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java index 44cbf153dee..2d668c7f229 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java @@ -77,11 +77,19 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid block params (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } - final TraceOptions traceOptions = - requestContext - .getOptionalParameter(1, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + final TraceOptions traceOptions; + try { + traceOptions = + requestContext + .getOptionalParameter(1, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } if (this.blockchainQueries.blockByHash(block.getHeader().getParentHash()).isPresent()) { final Collection results = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java index b1216885f1a..da795439cf3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java @@ -59,11 +59,19 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } - final TraceOptions traceOptions = - requestContext - .getOptionalParameter(1, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + final TraceOptions traceOptions; + try { + traceOptions = + requestContext + .getOptionalParameter(1, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameters (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } final Collection results = Tracer.processTracing( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java index dce3ab1ebf1..eb90edabb95 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java @@ -61,11 +61,19 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { protected Object resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { final Optional blockHash = getBlockchainQueries().getBlockHashByNumber(blockNumber); - final TraceOptions traceOptions = - request - .getOptionalParameter(1, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + final TraceOptions traceOptions; + try { + traceOptions = + request + .getOptionalParameter(1, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } return blockHash .flatMap( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java index 9de8108e679..ad46d981ac8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java @@ -55,10 +55,17 @@ public String getName() { @Override protected TraceOptions getTraceOptions(final JsonRpcRequestContext requestContext) { - return requestContext - .getOptionalParameter(2, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + try { + return requestContext + .getOptionalParameter(2, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameters (index 2)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java index 8ce0052b8b8..8ec14dc4ad5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java @@ -17,11 +17,13 @@ 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTracer; 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.DebugTraceTransactionResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata; @@ -48,15 +50,31 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final Optional transactionWithMetadata = blockchain.transactionByHash(hash); if (transactionWithMetadata.isPresent()) { - final TraceOptions traceOptions = - requestContext - .getOptionalParameter(1, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + final TraceOptions traceOptions; + try { + traceOptions = + requestContext + .getOptionalParameter(1, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } final DebugTraceTransactionResult debugTraceTransactionResult = debugTraceTransactionResult(hash, transactionWithMetadata.get(), traceOptions); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java index 44fb91689d0..9c7cf5e7a85 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java @@ -17,9 +17,11 @@ 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; 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.TransactionCompleteResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -42,8 +44,24 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); - final int index = requestContext.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } + final int index; + try { + index = requestContext.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction id parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_ID_PARAMS, + e); + } final Optional transactionWithMetadata = blockchain.transactionByBlockHashAndIndex(hash, index); final TransactionResult result = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java index 6a419d35c54..a5383f6680d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java @@ -50,7 +50,15 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { @Override protected Object resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { - final int index = request.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + final int index; + try { + index = request.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction index parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_INDEX_PARAMS, + e); + } final Optional transactionWithMetadata = getBlockchainQueries().transactionByBlockNumberAndIndex(blockNumber, index); return transactionWithMetadata.map(TransactionCompleteResult::new).orElse(null); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java index 8221de1f3f1..90e7a6a1edc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java @@ -17,6 +17,7 @@ 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.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; @@ -50,7 +51,15 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final JsonRpcSuccessResponse jsonRpcSuccessResponse = new JsonRpcSuccessResponse(requestContext.getRequest().getId(), getResult(hash)); return jsonRpcSuccessResponse; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java index 78c5f3b6504..a437cd86dc2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java @@ -17,8 +17,10 @@ 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.exception.InvalidJsonRpcParameters; 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.TransactionReceiptResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptRootResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptStatusResult; @@ -46,7 +48,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final TransactionReceiptResult result = blockchainQueries .transactionReceiptByTransactionHash(hash, protocolSchedule) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java index 70b232faab2..272014d3bc4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter; 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -68,7 +69,13 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } - final String rawTransaction = requestContext.getRequiredParameter(0, String.class); + final String rawTransaction; + try { + rawTransaction = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction parameters (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); + } final Transaction transaction; try { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java index c50525cef82..9882257143c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java @@ -18,9 +18,11 @@ 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.debug.TraceOptions; @@ -56,7 +58,12 @@ protected TraceOptions getTraceOptions(final JsonRpcRequestContext requestContex private Set getTraceTypes( final JsonRpcRequestContext requestContext) { - return requestContext.getRequiredParameter(1, TraceTypeParameter.class).getTraceTypes(); + try { + return requestContext.getRequiredParameter(1, TraceTypeParameter.class).getTraceTypes(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid trace type parameter (index 1)", RpcErrorType.INVALID_TRACE_TYPE_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java index 5b14019b070..2cbeb8ee7f8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java @@ -98,7 +98,7 @@ protected Object resultByBlockNumber( } catch (final Exception e) { LOG.error("Error parsing trace_callMany parameters: {}", e.getLocalizedMessage()); return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_TRACE_CALL_MANY_PARAMS); } final Optional maybeBlockHeader = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java index 2837e93e136..a1460c5aa24 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java @@ -17,6 +17,7 @@ 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -54,8 +55,24 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } - final Hash transactionHash = requestContext.getRequiredParameter(0, Hash.class); - final List traceNumbersAsStrings = requestContext.getRequiredParameter(1, List.class); + final Hash transactionHash; + try { + transactionHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction has parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } + final List traceNumbersAsStrings; + try { + traceNumbersAsStrings = requestContext.getRequiredParameter(1, List.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid trace numbers parameters (index 1)", + RpcErrorType.INVALID_TRACE_NUMBERS_PARAMS, + e); + } final List traceAddress = traceNumbersAsStrings.stream() .map(t -> Integer.parseInt(((String) t).substring(2), 16)) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java index a69414900f7..a7205698752 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java @@ -18,6 +18,7 @@ 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -70,9 +71,20 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } - final var rawTransaction = requestContext.getRequiredParameter(0, String.class); - final TraceTypeParameter traceTypeParameter = - requestContext.getRequiredParameter(1, TraceTypeParameter.class); + final String rawTransaction; + try { + rawTransaction = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction parameters (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); + } + final TraceTypeParameter traceTypeParameter; + try { + traceTypeParameter = requestContext.getRequiredParameter(1, TraceTypeParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid trace type parameter (index 1)", RpcErrorType.INVALID_TRACE_TYPE_PARAMS, e); + } LOG.trace( "Received RPC rpcName={} rawTx={} traceType={}", getName(), @@ -85,7 +97,7 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("rawTx decoded to transaction {}", transaction); } catch (final RLPException | IllegalArgumentException e) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_TRANSACTION_PARAMS); } final Set traceTypes = traceTypeParameter.getTraceTypes(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java index 50e580cd86d..a8b3bbc46de 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java @@ -83,8 +83,13 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { @Override protected ArrayNode resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { - final TraceTypeParameter traceTypeParameter = - request.getRequiredParameter(1, TraceTypeParameter.class); + final TraceTypeParameter traceTypeParameter; + try { + traceTypeParameter = request.getRequiredParameter(1, TraceTypeParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid trace type parameter (index 1)", RpcErrorType.INVALID_TRACE_TYPE_PARAMS, e); + } LOG.trace( "Received RPC rpcName={} block={} traceType={}", diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java index 55d1c0569d9..b79b9620e8d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java @@ -17,9 +17,11 @@ 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; 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.query.BlockchainQueries; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; @@ -45,7 +47,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash transactionHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash transactionHash; + try { + transactionHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } LOG.trace("Received RPC rpcName={} txHash={}", getName(), transactionHash); return new JsonRpcSuccessResponse( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java index 67e90d55b5a..8dc38135c60 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java @@ -54,8 +54,16 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final Collection pendingTransactions = transactionPool.getPendingTransactions(); - final Integer limit = - requestContext.getOptionalParameter(0, Integer.class).orElse(pendingTransactions.size()); + final int limit; + try { + limit = + requestContext.getOptionalParameter(0, Integer.class).orElse(pendingTransactions.size()); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction limit parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_LIMIT_PARAMS, + e); + } final List filters; try { filters = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java index df169560f59..7df76973ac9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java @@ -186,7 +186,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) if (!getWithdrawalsValidator( protocolSchedule.get(), newHead, maybePayloadAttributes.get().getTimestamp()) .validateWithdrawals(withdrawals)) { - return new JsonRpcErrorResponse(requestId, getInvalidParametersError()); + return new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java index 369d7a387a4..02ccf5d2311 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java @@ -24,7 +24,6 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getDepositRequestValidator; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getWithdrawalRequestValidator; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.datatypes.Address; @@ -42,7 +41,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestParameter; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; 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; @@ -118,8 +116,15 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) e); } - final Optional> maybeVersionedHashParam = - requestContext.getOptionalList(1, String.class); + final Optional> maybeVersionedHashParam; + try { + maybeVersionedHashParam = requestContext.getOptionalList(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcRequestException( + "Invalid versioned hash parameters (index 1)", + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, + e); + } final Object reqId = requestContext.getRequest().getId(); @@ -174,8 +179,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) if (!getWithdrawalsValidator( protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) .validateWithdrawals(maybeWithdrawals)) { - return new JsonRpcErrorResponse( - reqId, new JsonRpcError(INVALID_PARAMS, "Invalid withdrawals")); + return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS); } final Optional> maybeDepositRequests = @@ -197,8 +201,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) if (!getWithdrawalRequestValidator( protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) .validateParameter(maybeWithdrawalRequests)) { - return new JsonRpcErrorResponse( - reqId, new JsonRpcError(INVALID_PARAMS, "Invalid withdrawal request")); + return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS); } final Optional> maybeConsolidationRequests = @@ -486,14 +489,15 @@ protected ValidationResult validateBlobs( if (maybeVersionedHashes.isEmpty() && !transactionVersionedHashes.isEmpty()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "Payload must contain versioned hashes for transactions"); + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, + "Payload must contain versioned hashes for transactions"); } // Validate versionedHashesParam if (maybeVersionedHashes.isPresent() && !maybeVersionedHashes.get().equals(transactionVersionedHashes)) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, "Versioned hashes from blob transactions do not match expected values"); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3.java index 393687743e9..7d13ecc02c4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3.java @@ -64,7 +64,7 @@ protected ValidationResult validateParameters( RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Missing excess blob gas field"); } else if (maybeVersionedHashParam == null || maybeVersionedHashParam.isEmpty()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field"); + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, "Missing versioned hashes field"); } else if (maybeBeaconBlockRootParam.isEmpty()) { return ValidationResult.invalid( RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4.java index 2465cdd8137..904ec08e5c2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4.java @@ -64,7 +64,7 @@ protected ValidationResult validateParameters( RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Missing excess blob gas field"); } else if (maybeVersionedHashParam == null || maybeVersionedHashParam.isEmpty()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field"); + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, "Missing versioned hashes field"); } else if (maybeBeaconBlockRootParam.isEmpty()) { return ValidationResult.invalid( RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java index 1c530c14cf6..f1b949ad639 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java @@ -16,6 +16,7 @@ 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -43,11 +44,16 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { return new JsonRpcSuccessResponse(requestContext.getRequest().getId()); } catch (final IllegalArgumentException invalidJsonRpcParameters) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_TARGET_GAS_LIMIT_PARAMS); } catch (final UnsupportedOperationException unsupportedOperationException) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.TARGET_GAS_LIMIT_MODIFICATION_UNSUPPORTED); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid target gas limit parameter (index 0)", + RpcErrorType.INVALID_TARGET_GAS_LIMIT_PARAMS, + e); } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TraceTypeParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TraceTypeParameter.java index 80ba8bf6736..1b8e3a19d2d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TraceTypeParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TraceTypeParameter.java @@ -17,6 +17,7 @@ import static java.util.Objects.isNull; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import java.util.List; import java.util.Objects; @@ -73,7 +74,9 @@ private void validateTraceTypes(final List traceTypesInput) .collect(Collectors.joining(", ")); if (!unsupportedTypes.isEmpty()) { - throw new InvalidJsonRpcParameters("Invalid trace types supplied: " + unsupportedTypes); + throw new InvalidJsonRpcParameters( + "Invalid trace types supplied: " + unsupportedTypes, + RpcErrorType.INVALID_TRACE_TYPE_PARAMS); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java index 7ca3e943993..12c496b639d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.datatypes.Wei; 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -73,7 +74,13 @@ public String getName() { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final Object id = requestContext.getRequest().getId(); final Optional user = requestContext.getUser(); - final String rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); + final String rawPrivateTransaction; + try { + rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); + } try { final PrivateTransaction privateTransaction = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java index 62a087dade7..39003358ede 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.enclave.types.PrivacyGroup; 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -70,7 +71,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final Object id = requestContext.getRequest().getId(); - final String rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); + final String rawPrivateTransaction; + try { + rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid private transaction parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_PARAMS, + e); + } try { final PrivateTransaction privateTransaction = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java index 7bdba8824a2..31bfc52c804 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java @@ -85,7 +85,7 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { privateFor = requestContext.getRequiredParameter(2, String[].class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid private for parameter (index 2)", RpcErrorType.INVALID_PRIVATE_FOR_PARAMS, e); + "Invalid private for parameters (index 2)", RpcErrorType.INVALID_PRIVATE_FOR_PARAMS, e); } final String privacyUserId = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java index d260647c843..0629b2d55d4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java @@ -19,11 +19,13 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter; 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; 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.privacy.PrivateTransactionGroupResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionLegacyResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionResult; @@ -57,7 +59,15 @@ public String getName() { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("Executing {}", RpcMethod.PRIV_GET_PRIVATE_TRANSACTION.getMethodName()); - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final String enclaveKey = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); final Optional maybePrivateTx; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java index f9bc4241048..a1844841f00 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter; 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -66,7 +67,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("Executing {}", RpcMethod.PRIV_GET_TRANSACTION_RECEIPT.getMethodName()); - final Hash pmtTransactionHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash pmtTransactionHash; + try { + pmtTransactionHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final String enclaveKey = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); final ExecutedPrivateTransaction privateTransaction; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java index 7ea2de0c016..bf9d49d4e9c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.api.util; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.encoding.EncodingContext; import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder; @@ -30,9 +31,11 @@ public static Transaction decodeRawTransaction(final String rawTransaction) Bytes txnBytes = Bytes.fromHexString(rawTransaction); return TransactionDecoder.decodeOpaqueBytes(txnBytes, EncodingContext.POOLED_TRANSACTION); } catch (final IllegalArgumentException e) { - throw new InvalidJsonRpcRequestException("Invalid raw transaction hex", e); + throw new InvalidJsonRpcRequestException( + "Invalid raw transaction hex", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); } catch (final RLPException r) { - throw new InvalidJsonRpcRequestException("Invalid RLP in raw transaction hex", r); + throw new InvalidJsonRpcRequestException( + "Invalid RLP in raw transaction hex", RpcErrorType.INVALID_TRANSACTION_PARAMS, r); } } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAtTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAtTest.java index d7840241d5a..7876693b4cc 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAtTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAtTest.java @@ -113,7 +113,7 @@ void testInvalidParamsResponseEmptyList() { Assertions.assertThat(response).isInstanceOf(JsonRpcErrorResponse.class); Assertions.assertThat(((JsonRpcErrorResponse) response).getErrorType()) - .isEqualByComparingTo(RpcErrorType.INVALID_PARAMS); + .isEqualByComparingTo(RpcErrorType.INVALID_TRANSACTION_PARAMS); } @Test @@ -129,7 +129,7 @@ void testInvalidParamsResponseNegative() { Assertions.assertThat(response).isInstanceOf(JsonRpcErrorResponse.class); Assertions.assertThat(((JsonRpcErrorResponse) response).getErrorType()) - .isEqualByComparingTo(RpcErrorType.INVALID_PARAMS); + .isEqualByComparingTo(RpcErrorType.INVALID_TRANSACTION_PARAMS); } @Test @@ -145,7 +145,7 @@ void testInvalidParamsResponseTooHigh() { Assertions.assertThat(response).isInstanceOf(JsonRpcErrorResponse.class); Assertions.assertThat(((JsonRpcErrorResponse) response).getErrorType()) - .isEqualByComparingTo(RpcErrorType.INVALID_PARAMS); + .isEqualByComparingTo(RpcErrorType.INVALID_TRANSACTION_PARAMS); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java index 5496224e257..cdca20cb00e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java @@ -738,7 +738,7 @@ protected EngineUpdateForkchoiceResult assertSuccessWithPayloadForForkchoiceResu } protected RpcErrorType expectedInvalidPayloadError() { - return RpcErrorType.INVALID_PARAMS; + return RpcErrorType.INVALID_WITHDRAWALS_PARAMS; } protected JsonRpcResponse resp( diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV1Test.java index d38d3994415..6993be3d7ae 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV1Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV1Test.java @@ -46,6 +46,6 @@ protected String getMethodName() { @Override protected RpcErrorType expectedInvalidPayloadError() { - return RpcErrorType.INVALID_PAYLOAD_ATTRIBUTES; + return RpcErrorType.INVALID_WITHDRAWALS_PARAMS; } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java index 7ae80313a1d..c3558ef3292 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java @@ -92,6 +92,6 @@ protected String getMethodName() { @Override protected RpcErrorType expectedInvalidPayloadError() { - return RpcErrorType.INVALID_PARAMS; + return RpcErrorType.INVALID_WITHDRAWALS_PARAMS; } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimitTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimitTest.java index f31ac5e986f..df9d9247c35 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimitTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimitTest.java @@ -50,7 +50,8 @@ public void failsWithInvalidValue() { assertThat(minerChangeTargetGasLimit.response(request)) .isEqualTo( - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS)); + new JsonRpcErrorResponse( + request.getRequest().getId(), RpcErrorType.INVALID_TARGET_GAS_LIMIT_PARAMS)); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java index 4d209b847ba..b44100ba6c3 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java @@ -78,7 +78,7 @@ public void requestIsMissingParameter() { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid transaction parameter (index 0)"); } @Test @@ -88,7 +88,7 @@ public void requestHasNullObjectParameter() { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid transaction parameter (index 0)"); } @Test @@ -99,7 +99,7 @@ public void requestHasNullArrayParameter() { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid transaction parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_intOverflow.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_intOverflow.json index 7f804359ab5..aac1138b583 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_intOverflow.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_intOverflow.json @@ -13,7 +13,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction id params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_00.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_00.json index 97240170b07..b6c8becdb2e 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_00.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_00.json @@ -12,7 +12,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction hash params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_01.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_01.json index 6d12441ac7e..5984be529b7 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_01.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_01.json @@ -12,7 +12,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction id params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParams.json index 64f1cdef765..f3c8fca4e56 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParams.json @@ -10,7 +10,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction hash params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_wrongParamType.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_wrongParamType.json index 977ea64f158..f4e3dea7753 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_wrongParamType.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_wrongParamType.json @@ -13,7 +13,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction id params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_typeMismatch.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_typeMismatch.json index 2263de69d16..0abcb4da7e9 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_typeMismatch.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_typeMismatch.json @@ -12,7 +12,7 @@ "id" : 406, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid transaction hash params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidTraceOptions.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidTraceOptions.json index 47f13b7287c..eb1bfbd30b1 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidTraceOptions.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidTraceOptions.json @@ -13,7 +13,7 @@ "id": 415, "error": { "code": -32602, - "message": "Invalid params" + "message": "Invalid trace type params" } }, "statusCode": 200 diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java index a0790c9fcdb..e4fd7bcff27 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java @@ -16,9 +16,11 @@ import org.hyperledger.besu.datatypes.Hash; 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.methods.JsonRpcMethod; 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.query.TransactionReceiptWithMetadata; import org.hyperledger.besu.ethereum.retesteth.RetestethContext; import org.hyperledger.besu.ethereum.rlp.RLP; @@ -40,7 +42,15 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash txHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash txHash; + try { + txHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final Optional receipt = context diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java index eeae7faa18b..d9cfafbaeab 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java @@ -15,9 +15,11 @@ package org.hyperledger.besu.ethereum.retesteth.methods; 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.methods.JsonRpcMethod; 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.retesteth.RetestethContext; public class TestModifyTimestamp implements JsonRpcMethod { @@ -35,7 +37,13 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final long epochSeconds = requestContext.getRequiredParameter(0, Long.class); + final long epochSeconds; + try { + epochSeconds = requestContext.getRequiredParameter(0, Long.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid timestamp parameter (index 0)", RpcErrorType.INVALID_TIMESTAMP_PARAMS, e); + } context.getRetestethClock().resetTime(epochSeconds); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true); } From 4acd7f120c6ddfe4ddef26cd734cd16c0e8ab390 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 19 Aug 2024 15:09:38 +1000 Subject: [PATCH 6/7] Change default for receipt compaction to be enabled (#7450) Signed-off-by: Jason Frame --- CHANGELOG.md | 1 + .../cli/options/stable/DataStorageOptions.java | 4 ++-- .../options/stable/DataStorageOptionsTest.java | 14 ++++++++++---- .../worldstate/DataStorageConfiguration.java | 2 +- .../RocksDBKeyValuePrivacyStorageFactory.java | 14 ++++++++------ .../rocksdb/RocksDBKeyValueStorageFactory.java | 18 +++++++++--------- .../BaseVersionedStorageFormat.java | 10 ++-------- .../configuration/DatabaseMetadata.java | 2 +- .../PrivacyVersionedStorageFormat.java | 12 +++--------- ...cksDBKeyValuePrivacyStorageFactoryTest.java | 13 ++++++------- .../RocksDBKeyValueStorageFactoryTest.java | 13 ++++++------- 11 files changed, 49 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9173e46fd5e..8945cdd1ee5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Upcoming Breaking Changes ### Breaking Changes +- Receipt compaction is enabled by default. It will no longer be possible to downgrade Besu to versions prior to 24.5.1. ### Additions and Improvements - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java index 6f5c037c0d3..3d53a595ec8 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java @@ -95,8 +95,8 @@ public class DataStorageOptions implements CLIOptions @Option( names = "--receipt-compaction-enabled", - description = "Enables compact storing of receipts (default: ${DEFAULT-VALUE}).", - arity = "1") + description = "Enables compact storing of receipts (default: ${DEFAULT-VALUE})", + fallbackValue = "true") private Boolean receiptCompactionEnabled = DEFAULT_RECEIPT_COMPACTION_ENABLED; @CommandLine.ArgGroup(validate = false) diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/stable/DataStorageOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/stable/DataStorageOptionsTest.java index 2086381825f..29fa3d66071 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/options/stable/DataStorageOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/options/stable/DataStorageOptionsTest.java @@ -126,13 +126,20 @@ public void bonsaiCodeUsingCodeHashEnabledCanBeDisabled() { "false"); } + @Test + public void receiptCompactionCanBeEnabledWithImplicitTrueValue() { + internalTestSuccess( + dataStorageConfiguration -> + assertThat(dataStorageConfiguration.getReceiptCompactionEnabled()).isEqualTo(true), + "--receipt-compaction-enabled"); + } + @Test public void receiptCompactionCanBeEnabled() { internalTestSuccess( dataStorageConfiguration -> assertThat(dataStorageConfiguration.getReceiptCompactionEnabled()).isEqualTo(true), - "--receipt-compaction-enabled", - "true"); + "--receipt-compaction-enabled=true"); } @Test @@ -140,8 +147,7 @@ public void receiptCompactionCanBeDisabled() { internalTestSuccess( dataStorageConfiguration -> assertThat(dataStorageConfiguration.getReceiptCompactionEnabled()).isEqualTo(false), - "--receipt-compaction-enabled", - "false"); + "--receipt-compaction-enabled=false"); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DataStorageConfiguration.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DataStorageConfiguration.java index 8d767f442aa..320e38733d4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DataStorageConfiguration.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DataStorageConfiguration.java @@ -26,7 +26,7 @@ public interface DataStorageConfiguration { boolean DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED = true; long MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT = DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD; int DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE = 5_000; - boolean DEFAULT_RECEIPT_COMPACTION_ENABLED = false; + boolean DEFAULT_RECEIPT_COMPACTION_ENABLED = true; DataStorageConfiguration DEFAULT_CONFIG = ImmutableDataStorageConfiguration.builder() diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactory.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactory.java index 909a2c5e90e..6debcc046e5 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactory.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactory.java @@ -45,9 +45,7 @@ public class RocksDBKeyValuePrivacyStorageFactory implements PrivacyKeyValueStor LoggerFactory.getLogger(RocksDBKeyValuePrivacyStorageFactory.class); private static final Set SUPPORTED_VERSIONS = EnumSet.of( - PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES, PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION, - PrivacyVersionedStorageFormat.BONSAI_WITH_VARIABLES, PrivacyVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION); private static final String PRIVATE_DATABASE_PATH = "private"; private final RocksDBKeyValueStorageFactory publicFactory; @@ -230,8 +228,12 @@ private Optional handleVersionUpgrade( // reflect the change to the runtime version, and return it. // Besu supports both formats of receipts so no upgrade is needed other than updating metadata - if (runtimeVersion == PrivacyVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION - || runtimeVersion == PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION) { + final VersionedStorageFormat existingVersionedStorageFormat = + existingPrivacyMetadata.getVersionedStorageFormat(); + if ((existingVersionedStorageFormat == PrivacyVersionedStorageFormat.BONSAI_WITH_VARIABLES + && runtimeVersion == PrivacyVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION) + || (existingVersionedStorageFormat == PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES + && runtimeVersion == PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION)) { final DatabaseMetadata metadata = new DatabaseMetadata(runtimeVersion); try { metadata.writeToDirectory(dataDir); @@ -247,8 +249,8 @@ private Optional handleVersionUpgrade( "Database unsafe upgrade detect: DB at %s is %s with version %s but version %s is expected. " + "Please check your config and review release notes for supported upgrade procedures.", dataDir, - existingPrivacyMetadata.getVersionedStorageFormat().getFormat().name(), - existingPrivacyMetadata.getVersionedStorageFormat().getVersion(), + existingVersionedStorageFormat.getFormat().name(), + existingVersionedStorageFormat.getVersion(), runtimeVersion.getVersion()); throw new StorageException(error); diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactory.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactory.java index 8e1a4fa5213..d53c9e57fde 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactory.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactory.java @@ -57,11 +57,7 @@ public class RocksDBKeyValueStorageFactory implements KeyValueStorageFactory { private static final Logger LOG = LoggerFactory.getLogger(RocksDBKeyValueStorageFactory.class); private static final EnumSet SUPPORTED_VERSIONED_FORMATS = - EnumSet.of( - FOREST_WITH_VARIABLES, - FOREST_WITH_RECEIPT_COMPACTION, - BONSAI_WITH_VARIABLES, - BONSAI_WITH_RECEIPT_COMPACTION); + EnumSet.of(FOREST_WITH_RECEIPT_COMPACTION, BONSAI_WITH_RECEIPT_COMPACTION); private static final String NAME = "rocksdb"; private final RocksDBMetricsFactory rocksDBMetricsFactory; private DatabaseMetadata databaseMetadata; @@ -329,8 +325,12 @@ private Optional handleVersionUpgrade( // reflect the change to the runtime version, and return it. // Besu supports both formats of receipts so no upgrade is needed other than updating metadata - if (runtimeVersion == BONSAI_WITH_RECEIPT_COMPACTION - || runtimeVersion == FOREST_WITH_RECEIPT_COMPACTION) { + final VersionedStorageFormat existingVersionedStorageFormat = + existingMetadata.getVersionedStorageFormat(); + if ((existingVersionedStorageFormat == BONSAI_WITH_VARIABLES + && runtimeVersion == BONSAI_WITH_RECEIPT_COMPACTION) + || (existingVersionedStorageFormat == FOREST_WITH_VARIABLES + && runtimeVersion == FOREST_WITH_RECEIPT_COMPACTION)) { final DatabaseMetadata metadata = new DatabaseMetadata(runtimeVersion); try { metadata.writeToDirectory(dataDir); @@ -346,8 +346,8 @@ private Optional handleVersionUpgrade( "Database unsafe downgrade detect: DB at %s is %s with version %s but version %s is expected. " + "Please check your config and review release notes for supported downgrade procedures.", dataDir, - existingMetadata.getVersionedStorageFormat().getFormat().name(), - existingMetadata.getVersionedStorageFormat().getVersion(), + existingVersionedStorageFormat.getFormat().name(), + existingVersionedStorageFormat.getVersion(), runtimeVersion.getVersion()); throw new StorageException(error); diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/BaseVersionedStorageFormat.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/BaseVersionedStorageFormat.java index 658bb24a0f8..ad3557636d2 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/BaseVersionedStorageFormat.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/BaseVersionedStorageFormat.java @@ -63,14 +63,8 @@ public enum BaseVersionedStorageFormat implements VersionedStorageFormat { public static BaseVersionedStorageFormat defaultForNewDB( final DataStorageConfiguration configuration) { return switch (configuration.getDatabaseFormat()) { - case FOREST -> - configuration.getReceiptCompactionEnabled() - ? FOREST_WITH_RECEIPT_COMPACTION - : FOREST_WITH_VARIABLES; - case BONSAI -> - configuration.getReceiptCompactionEnabled() - ? BONSAI_WITH_RECEIPT_COMPACTION - : BONSAI_WITH_VARIABLES; + case FOREST -> FOREST_WITH_RECEIPT_COMPACTION; + case BONSAI -> BONSAI_WITH_RECEIPT_COMPACTION; }; } diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/DatabaseMetadata.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/DatabaseMetadata.java index 46dbb9e7403..a72db7c322b 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/DatabaseMetadata.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/DatabaseMetadata.java @@ -74,7 +74,7 @@ public static DatabaseMetadata defaultForNewDb(final BesuConfiguration besuConfi * @return the metadata to use for new db */ public static DatabaseMetadata defaultForNewPrivateDb() { - return new DatabaseMetadata(PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES); + return new DatabaseMetadata(PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); } /** diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/PrivacyVersionedStorageFormat.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/PrivacyVersionedStorageFormat.java index 87ff357e16d..ca5988dc75f 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/PrivacyVersionedStorageFormat.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/PrivacyVersionedStorageFormat.java @@ -32,7 +32,7 @@ public enum PrivacyVersionedStorageFormat implements VersionedStorageFormat { * Current Forest version, with receipts using compaction, in order to make Receipts use less disk * space */ - FOREST_WITH_RECEIPT_COMPACTION(BaseVersionedStorageFormat.FOREST_WITH_VARIABLES, 2), + FOREST_WITH_RECEIPT_COMPACTION(BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION, 2), /** Original Bonsai version, not used since replace by BONSAI_WITH_VARIABLES */ BONSAI_ORIGINAL(BaseVersionedStorageFormat.BONSAI_ORIGINAL, 1), /** @@ -64,14 +64,8 @@ public enum PrivacyVersionedStorageFormat implements VersionedStorageFormat { public static VersionedStorageFormat defaultForNewDB( final DataStorageConfiguration configuration) { return switch (configuration.getDatabaseFormat()) { - case FOREST -> - configuration.getReceiptCompactionEnabled() - ? FOREST_WITH_RECEIPT_COMPACTION - : FOREST_WITH_VARIABLES; - case BONSAI -> - configuration.getReceiptCompactionEnabled() - ? BONSAI_WITH_RECEIPT_COMPACTION - : BONSAI_WITH_VARIABLES; + case FOREST -> FOREST_WITH_RECEIPT_COMPACTION; + case BONSAI -> BONSAI_WITH_RECEIPT_COMPACTION; }; } diff --git a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactoryTest.java b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactoryTest.java index 5dd485cb7af..17a3fb874a4 100644 --- a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactoryTest.java +++ b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactoryTest.java @@ -77,7 +77,7 @@ public void shouldDetectVersion1MetadataIfPresent() throws Exception { try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) - .isEqualTo(PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES); + .isEqualTo(PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); } } @@ -97,7 +97,7 @@ public void shouldCreateCorrectMetadataFileForLatestVersion() throws Exception { // Side effect is creation of the Metadata version file try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) - .isEqualTo(PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES); + .isEqualTo(PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); } } @@ -116,8 +116,8 @@ public void shouldUpdateCorrectMetadataFileForLatestVersion( try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { final BaseVersionedStorageFormat expectedBaseVersion = dataStorageFormat == BONSAI - ? BaseVersionedStorageFormat.BONSAI_WITH_VARIABLES - : BaseVersionedStorageFormat.FOREST_WITH_VARIABLES; + ? BaseVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION + : BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION; assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) .isEqualTo(expectedBaseVersion); } @@ -130,8 +130,8 @@ public void shouldUpdateCorrectMetadataFileForLatestVersion( privacyStorageFactory.create(segment, commonConfiguration, metricsSystem)) { final PrivacyVersionedStorageFormat expectedPrivacyVersion = dataStorageFormat == BONSAI - ? PrivacyVersionedStorageFormat.BONSAI_WITH_VARIABLES - : PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES; + ? PrivacyVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION + : PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION; assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) .isEqualTo(expectedPrivacyVersion); } @@ -145,7 +145,6 @@ public void shouldUpdateCorrectMetadataFileForLatestVersionWithReceiptCompaction final Path tempDataDir = temporaryFolder.resolve("data"); final Path tempDatabaseDir = temporaryFolder.resolve("db"); mockCommonConfiguration(tempDataDir, tempDatabaseDir, dataStorageFormat); - when(dataStorageConfiguration.getReceiptCompactionEnabled()).thenReturn(true); final RocksDBKeyValueStorageFactory storageFactory = new RocksDBKeyValueStorageFactory( diff --git a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactoryTest.java b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactoryTest.java index a86c5ba807b..7148f601cbd 100644 --- a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactoryTest.java +++ b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactoryTest.java @@ -76,8 +76,8 @@ public void shouldCreateCorrectMetadataFileForLatestVersionForNewDb( // Side effect is creation of the Metadata version file final BaseVersionedStorageFormat expectedVersion = dataStorageFormat == BONSAI - ? BaseVersionedStorageFormat.BONSAI_WITH_VARIABLES - : BaseVersionedStorageFormat.FOREST_WITH_VARIABLES; + ? BaseVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION + : BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION; assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) .isEqualTo(expectedVersion); } @@ -90,7 +90,6 @@ public void shouldCreateCorrectMetadataFileForLatestVersionForNewDbWithReceiptCo final Path tempDataDir = temporaryFolder.resolve("data"); final Path tempDatabaseDir = temporaryFolder.resolve("db"); mockCommonConfiguration(tempDataDir, tempDatabaseDir, dataStorageFormat); - when(dataStorageConfiguration.getReceiptCompactionEnabled()).thenReturn(true); final RocksDBKeyValueStorageFactory storageFactory = new RocksDBKeyValueStorageFactory( @@ -129,7 +128,7 @@ public void shouldFailIfDbExistsAndNoMetadataFileFound() throws Exception { } @Test - public void shouldDetectCorrectMetadataV1() throws Exception { + public void shouldDetectCorrectMetadataV1AndUpgrade() throws Exception { final Path tempDataDir = temporaryFolder.resolve("data"); final Path tempDatabaseDir = temporaryFolder.resolve("db"); Files.createDirectories(tempDataDir); @@ -143,7 +142,7 @@ public void shouldDetectCorrectMetadataV1() throws Exception { try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) - .isEqualTo(BaseVersionedStorageFormat.BONSAI_WITH_VARIABLES); + .isEqualTo(BaseVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION); assertThat(storageFactory.isSegmentIsolationSupported()).isTrue(); } } @@ -240,7 +239,7 @@ public void shouldDetectCorrectMetadataV2AndSetSegmentationFieldDuringCreation() () -> rocksDbConfiguration, segments, RocksDBMetricsFactory.PUBLIC_ROCKS_DB_METRICS); try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) - .isEqualTo(BaseVersionedStorageFormat.FOREST_WITH_VARIABLES); + .isEqualTo(BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); assertThatCode(storageFactory::isSegmentIsolationSupported).doesNotThrowAnyException(); } } @@ -299,7 +298,7 @@ public void shouldCreateDBCorrectlyIfSymlink() throws Exception { // created correctly try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempRealDataDir).getVersionedStorageFormat()) - .isEqualTo(BaseVersionedStorageFormat.FOREST_WITH_VARIABLES); + .isEqualTo(BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); } } From f9048cf3e2f772ba70802f19f37320cdff85bc49 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 19 Aug 2024 15:50:57 +1000 Subject: [PATCH 7/7] 5098 branch 23 rename is complete transaction (#7479) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../fork/frontier/EthGetBlockByNumberIntegrationTest.java | 2 +- .../api/jsonrpc/execution/TracedJsonRpcProcessor.java | 2 +- .../api/jsonrpc/internal/methods/DebugTraceBlockByHash.java | 2 +- .../ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java | 2 +- .../api/jsonrpc/internal/methods/EthGetBlockByHash.java | 4 ++-- .../api/jsonrpc/internal/methods/EthGetBlockByNumber.java | 4 ++-- .../besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java | 2 +- .../ethereum/api/jsonrpc/internal/response/RpcErrorType.java | 4 ++-- .../besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java | 4 ++-- .../api/jsonrpc/internal/methods/EthGetBlockByHashTest.java | 4 ++-- .../api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java | 4 ++-- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java index 966cda12008..3798cbe507c 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java @@ -437,7 +437,7 @@ public void missingHashesOrTransactionParameter() { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is transaction complete parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); } /** diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java index f1a799cf638..ec0e6aef64a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java @@ -84,7 +84,7 @@ public JsonRpcResponse process( case INVALID_GAS_PRICE_PARAMS: case INVALID_HASH_RATE_PARAMS: case INVALID_ID_PARAMS: - case INVALID_IS_TRANSACTION_COMPLETE_PARAMS: + case INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS: case INVALID_LOG_FILTER_PARAMS: case INVALID_LOG_LEVEL_PARAMS: case INVALID_MAX_RESULTS_PARAMS: diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java index da795439cf3..4c1d3bfc2a6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java @@ -68,7 +68,7 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .orElse(TraceOptions.DEFAULT); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid transaction trace parameters (index 1)", + "Invalid transaction trace parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java index ad46d981ac8..d309f8dfdd8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java @@ -62,7 +62,7 @@ protected TraceOptions getTraceOptions(final JsonRpcRequestContext requestContex .orElse(TraceOptions.DEFAULT); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid transaction trace parameters (index 2)", + "Invalid transaction trace parameter (index 2)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java index 09b1c2f9523..875daea7f13 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java @@ -97,8 +97,8 @@ private boolean isCompleteTransactions(final JsonRpcRequestContext requestContex return requestContext.getRequiredParameter(1, Boolean.class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid is complete transaction parameter (index 1)", - RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS, + "Invalid return complete transaction parameter (index 1)", + RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS, e); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java index 5e0bc9c7ab4..8e0954144d8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java @@ -128,8 +128,8 @@ private boolean isCompleteTransactions(final JsonRpcRequestContext request) { return request.getRequiredParameter(1, Boolean.class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid is transaction complete parameter (index 1)", - RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS, + "Invalid return complete transaction parameter (index 1)", + RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS, e); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java index a1460c5aa24..b346637ec25 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java @@ -60,7 +60,7 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { transactionHash = requestContext.getRequiredParameter(0, Hash.class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid transaction has parameter (index 0)", + "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java index cb19d2e7a35..009fca38fc0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java @@ -66,8 +66,8 @@ public enum RpcErrorType implements RpcMethodError { INVALID_GAS_PRICE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid gas price params"), INVALID_HASH_RATE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid hash rate params"), INVALID_ID_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid ID params"), - INVALID_IS_TRANSACTION_COMPLETE_PARAMS( - INVALID_PARAMS_ERROR_CODE, "Invalid is transaction complete params"), + INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid return complete transaction params"), INVALID_LOG_FILTER_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid log filter params"), INVALID_LOG_LEVEL_PARAMS( INVALID_PARAMS_ERROR_CODE, "Invalid log level params (missing or incorrect)"), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index dcfd198d6e1..bb5cb68a2ae 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -784,7 +784,7 @@ public void getBlockByHashWithMissingBooleanParameter() throws Exception { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } @@ -854,7 +854,7 @@ public void getBlockByHashWithInvalidBooleanParameter() throws Exception { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java index 0fc8969c938..e79fff04f7f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java @@ -69,7 +69,7 @@ public void exceptionWhenNoHashSupplied() { public void exceptionWhenNoBoolSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(ZERO_HASH))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is complete transaction parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } @@ -85,7 +85,7 @@ public void exceptionWhenHashParamInvalid() { public void exceptionWhenBoolParamInvalid() { assertThatThrownBy(() -> method.response(requestWithParams(ZERO_HASH, "maybe"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is complete transaction parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java index bc6ec997f34..254d0fbe9e8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java @@ -121,7 +121,7 @@ public void exceptionWhenNoNumberSupplied() { public void exceptionWhenNoBoolSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("0"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is transaction complete parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } @@ -137,7 +137,7 @@ public void exceptionWhenNumberParamInvalid() { public void exceptionWhenBoolParamInvalid() { assertThatThrownBy(() -> method.response(requestWithParams("0", "maybe"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is transaction complete parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); }