Skip to content

Commit

Permalink
Validate non null required paremeters
Browse files Browse the repository at this point in the history
Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
  • Loading branch information
Gabriel-Trintinalia committed Aug 29, 2023
1 parent ee0fa6b commit b71de12
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.ProtocolContext;
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.parameters.DepositParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineExecutionPayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineNewPayloadRequestParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
Expand Down Expand Up @@ -64,6 +66,7 @@

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -99,26 +102,25 @@ public AbstractEngineNewPayload(
@Override
public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) {
engineCallListener.executionEngineCalled();

final EnginePayloadParameter blockParam =
requestContext.getRequiredParameter(0, EnginePayloadParameter.class);

final Optional<List<String>> maybeVersionedHashParam =
requestContext.getOptionalList(1, String.class);

final Object reqId = requestContext.getRequest().getId();

Optional<String> maybeParentBeaconBlockRootParam =
requestContext.getOptionalParameter(2, String.class);
final Optional<Bytes32> maybeParentBeaconBlockRoot =
maybeParentBeaconBlockRootParam.map(Bytes32::fromHexString);
EngineNewPayloadRequestParameter requestParameters;
try {
requestParameters = getEngineNewPayloadRequestParams(requestContext);
} catch (InvalidJsonRpcParameters exception) {
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(),
new JsonRpcError(INVALID_PARAMS, exception.getMessage()));
}

final ValidationResult<RpcErrorType> parameterValidationResult =
validateParameters(blockParam, maybeVersionedHashParam, maybeParentBeaconBlockRootParam);
validateParameters(requestParameters);

if (!parameterValidationResult.isValid()) {
return new JsonRpcErrorResponse(reqId, parameterValidationResult);
}

EngineExecutionPayloadParameter blockParam = requestParameters.getExecutionPayload();
final ValidationResult<RpcErrorType> forkValidationResult =
validateForkSupported(blockParam.getTimestamp());
if (!forkValidationResult.isValid()) {
Expand All @@ -127,7 +129,8 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)

final Optional<List<VersionedHash>> maybeVersionedHashes;
try {
maybeVersionedHashes = extractVersionedHashes(maybeVersionedHashParam);
maybeVersionedHashes =
extractVersionedHashes(requestParameters.getExpectedBlobVersionedHashes());
} catch (RuntimeException ex) {
return respondWithInvalid(reqId, blockParam, null, INVALID, "Invalid versionedHash");
}
Expand Down Expand Up @@ -213,7 +216,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
blockParam.getExcessBlobGas() == null
? null
: BlobGas.fromHexString(blockParam.getExcessBlobGas()),
maybeParentBeaconBlockRoot.orElse(null),
requestParameters.getParentBeaconBlockRoot().map(Bytes32::fromHexString).orElse(null),
maybeDeposits.map(BodyValidation::depositsRoot).orElse(null),
headerFunctions);

Expand Down Expand Up @@ -318,7 +321,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)

JsonRpcResponse respondWith(
final Object requestId,
final EnginePayloadParameter param,
final EngineExecutionPayloadParameter param,
final Hash latestValidHash,
final EngineStatus status) {
if (INVALID.equals(status) || INVALID_BLOCK_HASH.equals(status)) {
Expand All @@ -343,7 +346,7 @@ JsonRpcResponse respondWith(

JsonRpcResponse respondWithInvalid(
final Object requestId,
final EnginePayloadParameter param,
final EngineExecutionPayloadParameter param,
final Hash latestValidHash,
final EngineStatus invalidStatus,
final String validationError) {
Expand Down Expand Up @@ -382,9 +385,7 @@ protected EngineStatus getInvalidBlockHashStatus() {
}

protected ValidationResult<RpcErrorType> validateParameters(
final EnginePayloadParameter parameter,
final Optional<List<String>> maybeVersionedHashParam,
final Optional<String> maybeBeaconBlockRootParam) {
final EngineNewPayloadRequestParameter params) {
return ValidationResult.valid();
}

Expand Down Expand Up @@ -475,6 +476,27 @@ private Optional<List<VersionedHash>> extractVersionedHashes(
.collect(Collectors.toList()));
}

/**
* Retrieves the new payload request parameters from the given JSON-RPC request context.
*
* @param requestContext the JSON-RPC request context
* @return a new instance of EngineNewPayloadRequestParameter
*/
public EngineNewPayloadRequestParameter getEngineNewPayloadRequestParams(
final JsonRpcRequestContext requestContext) {

final EngineExecutionPayloadParameter payload =
requestContext.getRequiredParameter(0, EngineExecutionPayloadParameter.class);
final String[] versionedHashes = requestContext.getRequiredParameter(1, String[].class);

final String parentBeaconBlockRoot = requestContext.getRequiredParameter(2, String.class);

return new EngineNewPayloadRequestParameter(
payload,
Optional.of(Arrays.stream(versionedHashes).toList()),
Optional.of(parentBeaconBlockRoot));
}

private void logImportedBlockInfo(final Block block, final double timeInS) {
final StringBuilder message = new StringBuilder();
message.append("Imported #%,d / %d tx");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import org.hyperledger.besu.datatypes.VersionedHash;
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.parameters.EngineExecutionPayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineNewPayloadRequestParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
Expand Down Expand Up @@ -60,6 +63,13 @@ protected EngineStatus getInvalidBlockHashStatus() {
return INVALID_BLOCK_HASH;
}

@Override
public EngineNewPayloadRequestParameter getEngineNewPayloadRequestParams(
final JsonRpcRequestContext requestContext) {
return new EngineNewPayloadRequestParameter(
requestContext.getRequiredParameter(0, EngineExecutionPayloadParameter.class));
}

@Override
protected ValidationResult<RpcErrorType> validateBlobs(
final List<Transaction> transactions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import org.hyperledger.besu.datatypes.VersionedHash;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineExecutionPayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineNewPayloadRequestParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
Expand Down Expand Up @@ -51,20 +53,25 @@ public String getName() {

@Override
protected ValidationResult<RpcErrorType> validateParameters(
final EnginePayloadParameter payloadParameter,
final Optional<List<String>> maybeVersionedHashParam,
final Optional<String> maybeBeaconBlockRootParam) {
if (payloadParameter.getBlobGasUsed() != null) {
final EngineNewPayloadRequestParameter params) {
if (params.getExecutionPayload().getBlobGasUsed() != null) {
return ValidationResult.invalid(
RpcErrorType.INVALID_PARAMS, "non-null BlobGasUsed pre-cancun");
}
if (payloadParameter.getExcessBlobGas() != null) {
if (params.getExecutionPayload().getExcessBlobGas() != null) {
return ValidationResult.invalid(
RpcErrorType.INVALID_PARAMS, "non-null ExcessBlobGas pre-cancun");
}
return ValidationResult.valid();
}

@Override
public EngineNewPayloadRequestParameter getEngineNewPayloadRequestParams(
final JsonRpcRequestContext requestContext) {
return new EngineNewPayloadRequestParameter(
requestContext.getRequiredParameter(0, EngineExecutionPayloadParameter.class));
}

@Override
protected ValidationResult<RpcErrorType> validateBlobs(
final List<Transaction> transactions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineNewPayloadRequestParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;

import java.util.List;
import java.util.Optional;

import io.vertx.core.Vertx;
Expand Down Expand Up @@ -52,20 +51,12 @@ public String getName() {

@Override
protected ValidationResult<RpcErrorType> validateParameters(
final EnginePayloadParameter payloadParameter,
final Optional<List<String>> maybeVersionedHashParam,
final Optional<String> maybeBeaconBlockRootParam) {
if (payloadParameter.getBlobGasUsed() == null || payloadParameter.getExcessBlobGas() == null) {
final EngineNewPayloadRequestParameter params) {
if (params.getExecutionPayload().getBlobGasUsed() == null
|| params.getExecutionPayload().getExcessBlobGas() == null) {
return ValidationResult.invalid(RpcErrorType.INVALID_PARAMS, "Missing blob gas fields");
} else if (maybeVersionedHashParam == null) {
return ValidationResult.invalid(
RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field");
} else if (maybeBeaconBlockRootParam.isEmpty()) {
return ValidationResult.invalid(
RpcErrorType.INVALID_PARAMS, "Missing parent beacon block root field");
} else {
return ValidationResult.valid();
}
return ValidationResult.valid();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.tuweni.bytes.Bytes32;

public class EnginePayloadParameter {
public class EngineExecutionPayloadParameter {
private final Hash blockHash;
private final Hash parentHash;
private final Address feeRecipient;
Expand Down Expand Up @@ -68,7 +68,7 @@ public class EnginePayloadParameter {
* @param deposits List of deposit parameters.
*/
@JsonCreator
public EnginePayloadParameter(
public EngineExecutionPayloadParameter(
@JsonProperty("blockHash") final Hash blockHash,
@JsonProperty("parentHash") final Hash parentHash,
@JsonProperty("feeRecipient") final Address feeRecipient,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters;

import java.util.List;
import java.util.Optional;

/** Represents the parameters for a new payload request in the Ethereum engine. */
public class EngineNewPayloadRequestParameter {

private final EngineExecutionPayloadParameter executionPayload;
private final Optional<List<String>> expectedBlobVersionedHashes;
private final Optional<String> parentBeaconBlockRoot;

/**
* Constructs a new payload request parameter with only an execution payload.
*
* @param payload the execution payload
*/
public EngineNewPayloadRequestParameter(final EngineExecutionPayloadParameter payload) {
this(payload, Optional.empty(), Optional.empty());
}

/**
* Constructs a new payload request parameter with an execution payload, expected blob versioned
* hashes, and a parent beacon block root.
*
* @param executionPayload the execution payload
* @param expectedBlobVersionedHashes the expected blob versioned hashes
* @param parentBeaconBlockRoot the parent beacon block root
*/
public EngineNewPayloadRequestParameter(
final EngineExecutionPayloadParameter executionPayload,
final Optional<List<String>> expectedBlobVersionedHashes,
final Optional<String> parentBeaconBlockRoot) {
this.executionPayload = executionPayload;
this.expectedBlobVersionedHashes = expectedBlobVersionedHashes;
this.parentBeaconBlockRoot = parentBeaconBlockRoot;
}

/**
* Returns the execution payload.
*
* @return the execution payload
*/
public EngineExecutionPayloadParameter getExecutionPayload() {
return executionPayload;
}

/**
* Returns the expected blob versioned hashes.
*
* @return the expected blob versioned hashes
*/
public Optional<List<String>> getExpectedBlobVersionedHashes() {
return expectedBlobVersionedHashes;
}

/**
* Returns the parent beacon block root.
*
* @return the parent beacon block root
*/
public Optional<String> getParentBeaconBlockRoot() {
return parentBeaconBlockRoot;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineExecutionPayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedLongParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
Expand Down Expand Up @@ -389,7 +389,7 @@ public void shouldReturnValidIfProtocolScheduleIsEmpty() {
assertValidResponse(mockHeader, resp);
}

protected JsonRpcResponse resp(final EnginePayloadParameter payload) {
protected JsonRpcResponse resp(final EngineExecutionPayloadParameter payload) {
Object[] params =
maybeParentBeaconBlockRoot
.map(bytes32 -> new Object[] {payload, null, bytes32.toHexString()})
Expand All @@ -398,17 +398,17 @@ protected JsonRpcResponse resp(final EnginePayloadParameter payload) {
new JsonRpcRequestContext(new JsonRpcRequest("2.0", this.method.getName(), params)));
}

protected EnginePayloadParameter mockEnginePayload(
protected EngineExecutionPayloadParameter mockEnginePayload(
final BlockHeader header, final List<String> txs) {
return mockEnginePayload(header, txs, null, null);
}

protected EnginePayloadParameter mockEnginePayload(
protected EngineExecutionPayloadParameter mockEnginePayload(
final BlockHeader header,
final List<String> txs,
final List<WithdrawalParameter> withdrawals,
final List<DepositParameter> deposits) {
return new EnginePayloadParameter(
return new EngineExecutionPayloadParameter(
header.getHash(),
header.getParentHash(),
header.getCoinbase(),
Expand Down
Loading

0 comments on commit b71de12

Please sign in to comment.