Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

EIP-7702: devnet-4 changes #7809

Merged
merged 51 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
c71d4af
warm up to address at tx start if account is delegated, restrict auth…
daniellehrner Oct 2, 2024
67bab68
Merge branch 'main' into fix/issue-7706/warmup_to_when_delegated
daniellehrner Oct 3, 2024
49a4411
rename requestsRoot to requestsHash
jframe Oct 9, 2024
196bf10
return no code if account has delegated code to precompile, treat pre…
daniellehrner Oct 9, 2024
a2abff2
make accessListWarmAddresses generic again
daniellehrner Oct 9, 2024
dcefdce
Merge branch 'fix/issue-7706/warmup_to_when_delegated' into pectra-de…
daniellehrner Oct 9, 2024
6393399
warm delegatee account if transaction destination has delegated code
daniellehrner Oct 9, 2024
1269cc1
Merge branch 'main' into pectra-devnet4-7702
daniellehrner Oct 10, 2024
d7e5686
* verify auth nonce less than 2**64-1 during auth processing
daniellehrner Oct 10, 2024
cdc9bd5
generalised requests flat encoding and engine api changes
jframe Oct 14, 2024
cee6abc
javadoc
jframe Oct 14, 2024
8f346f4
get tests passing
jframe Oct 15, 2024
4e12780
get tests passing
jframe Oct 15, 2024
42e6865
Merge remote-tracking branch 'upstream/main' into 7685_flat_encoding
jframe Oct 15, 2024
f0d5a24
clean code
jframe Oct 15, 2024
0424317
change requests to single requestData for each requestType
jframe Oct 15, 2024
86f5049
fix PoWBlockCreatorTest after requests data type change
jframe Oct 15, 2024
722823e
don't return request type in getPayload result
jframe Oct 15, 2024
24a33e7
include requests in t8n response
jframe Oct 16, 2024
24de847
update contract addresses for consolidation requests and withdrawal r…
jframe Oct 16, 2024
532cb9d
fix requestHash calculation
jframe Oct 16, 2024
079bcfd
Ensure that execution requests always return a response
jframe Oct 16, 2024
9a98c12
Merge branch 'main' into pectra-devnet4-7702
daniellehrner Oct 16, 2024
c19f93f
Merge remote-tracking branch 'jason/7685_flat_encoding' into pectra-d…
daniellehrner Oct 16, 2024
bdb0cb3
added and fixed bound checks, fixed some compilation errors after the…
daniellehrner Oct 16, 2024
eff46b0
revert changes to evm tool spec tests
jframe Oct 17, 2024
1fdf0db
clean up
jframe Oct 17, 2024
9c2a623
replace AbstractSystemCallRequestProcessor to concrete class and remo…
jframe Oct 17, 2024
afd9023
spotless
jframe Oct 17, 2024
20ca19e
update evmtool tests for 7685 changes
jframe Oct 17, 2024
3ee1b31
use empty requests hash prague fork at genesis
jframe Oct 17, 2024
21b7aae
review suggestions
jframe Oct 17, 2024
6457be5
Merge remote-tracking branch 'jason/7685_flat_encoding' into pectra-d…
daniellehrner Oct 17, 2024
7522a77
temporarily comment out osakaTime from Prague
daniellehrner Oct 17, 2024
89d4950
Merge branch 'main' into pectra-devnet4-7702
daniellehrner Oct 17, 2024
7574c84
engine API validation
jframe Oct 18, 2024
ac812b2
Merge remote-tracking branch 'upstream/main' into 7685_flat_encoding
jframe Oct 18, 2024
95d1606
update plugin API hash
jframe Oct 18, 2024
4c62cae
fix GenesisStateTest
jframe Oct 18, 2024
9a317b1
Merge remote-tracking branch 'jason/7685_flat_encoding' into pectra-d…
daniellehrner Oct 18, 2024
8ab3aac
comment out unused evmWorldUpdater.parentUpdater() check
daniellehrner Oct 21, 2024
9ebc32b
Merge branch 'main' into pectra-devnet-4
daniellehrner Oct 24, 2024
75a3397
added CodeDelegationProcessorTest
daniellehrner Oct 27, 2024
759fab9
Merge branch 'main' into pectra-devnet-4
daniellehrner Nov 8, 2024
97af121
Merge branch 'main' into pectra-devnet-4
daniellehrner Nov 25, 2024
747cf4f
code clean up
daniellehrner Nov 27, 2024
9d5a47b
Merge branch 'main' into pectra-devnet-4
daniellehrner Nov 27, 2024
23b7ca1
Merge branch 'main' into pectra-devnet-4
daniellehrner Nov 29, 2024
2ea76d7
spotless
daniellehrner Nov 29, 2024
a8647e2
Merge branch 'main' into pectra-devnet-4
daniellehrner Dec 2, 2024
734a416
Merge branch 'main' into pectra-devnet-4
daniellehrner Dec 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
generalised requests flat encoding and engine api changes
Signed-off-by: Jason Frame <jason.frame@consensys.net>
  • Loading branch information
jframe committed Oct 14, 2024
commit cdc9bd5b6f76dcbb02bd67e9474162b8b80ebb72
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.BlockValueCalculator;
import org.hyperledger.besu.ethereum.core.BlockWithReceipts;
import org.hyperledger.besu.ethereum.core.Request;

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

/** Wrapper for payload plus extra info. */
public class PayloadWrapper {
private final PayloadIdentifier payloadIdentifier;
private final BlockWithReceipts blockWithReceipts;
private final Wei blockValue;
private final Optional<List<Request>> requests;

/**
* Construct a wrapper with the following fields.
Expand All @@ -32,10 +37,13 @@ public class PayloadWrapper {
* @param blockWithReceipts Block with receipts
*/
public PayloadWrapper(
final PayloadIdentifier payloadIdentifier, final BlockWithReceipts blockWithReceipts) {
final PayloadIdentifier payloadIdentifier,
final BlockWithReceipts blockWithReceipts,
final Optional<List<Request>> requests) {
this.blockWithReceipts = blockWithReceipts;
this.payloadIdentifier = payloadIdentifier;
this.blockValue = BlockValueCalculator.calculateBlockValue(blockWithReceipts);
this.requests = requests;
}

/**
Expand Down Expand Up @@ -64,4 +72,13 @@ public PayloadIdentifier payloadIdentifier() {
public BlockWithReceipts blockWithReceipts() {
return blockWithReceipts;
}

/**
* Get the requests
*
* @return requests
*/
public Optional<List<Request>> requests() {
return requests;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.BlockProcessingOutputs;
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.blockcreation.BlockCreator.BlockCreationResult;
Expand Down Expand Up @@ -299,10 +300,13 @@ public PayloadIdentifier preparePayload(
.getBlock();

BlockProcessingResult result = validateProposedBlock(emptyBlock);
// TODO include the requests in the payload wrapper
if (result.isSuccessful()) {
mergeContext.putPayloadById(
new PayloadWrapper(
payloadIdentifier, new BlockWithReceipts(emptyBlock, result.getReceipts())));
payloadIdentifier,
new BlockWithReceipts(emptyBlock, result.getReceipts()),
result.getYield().flatMap(BlockProcessingOutputs::getRequests)));
LOG.info(
"Start building proposals for block {} identified by {}",
emptyBlock.getHeader().getNumber(),
Expand Down Expand Up @@ -469,7 +473,9 @@ private void evaluateNewBlock(

mergeContext.putPayloadById(
new PayloadWrapper(
payloadIdentifier, new BlockWithReceipts(bestBlock, resultBest.getReceipts())));
payloadIdentifier,
new BlockWithReceipts(bestBlock, resultBest.getReceipts()),
resultBest.getYield().flatMap(BlockProcessingOutputs::getRequests)));
LOG.atDebug()
.setMessage(
"Successfully built block {} for proposal identified by {}, with {} transactions, in {}ms")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ public class ProposalTest {
new BlockBody(
Collections.emptyList(),
Collections.emptyList(),
Optional.of(Collections.emptyList()),
Optional.empty()));
Optional.of(Collections.emptyList())));

@Test
public void canRoundTripProposalMessage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public JsonRpcResponse process(
case INVALID_TRANSACTION_INDEX_PARAMS:
case INVALID_TRANSACTION_LIMIT_PARAMS:
case INVALID_TRANSACTION_TRACE_PARAMS:
case INVALID_VERSIONED_HASH_PARAMS:
case INVALID_REQUESTS_PARAMS:
case INVALID_VOTE_TYPE_PARAMS:
case INVALID_WITHDRAWALS_PARAMS:
metricSpan.setStatus(StatusCode.ERROR, "Invalid Params");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,23 @@
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID_BLOCK_HASH;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.SYNCING;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.VALID;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getConsolidationRequestValidator;
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 org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.RequestType;
import org.hyperledger.besu.datatypes.VersionedHash;
import org.hyperledger.besu.datatypes.Wei;
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.InvalidJsonRpcRequestException;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ConsolidationRequestParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequestParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
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.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
Expand All @@ -64,7 +59,6 @@
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator;
import org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil;
import org.hyperledger.besu.ethereum.rlp.RLPException;
import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
import org.hyperledger.besu.plugin.services.exception.StorageException;
Expand All @@ -75,6 +69,7 @@
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import io.vertx.core.Vertx;
import io.vertx.core.json.Json;
Expand Down Expand Up @@ -141,8 +136,22 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
final Optional<Bytes32> maybeParentBeaconBlockRoot =
maybeParentBeaconBlockRootParam.map(Bytes32::fromHexString);

final Optional<List<String>> maybeRequestsParam;
try {
maybeRequestsParam = requestContext.getOptionalList(3, String.class);
} catch (JsonRpcParameterException e) {
throw new InvalidJsonRpcRequestException(
"Invalid execution request parameters (index 3)",
RpcErrorType.INVALID_REQUESTS_PARAMS,
e);
}

final ValidationResult<RpcErrorType> parameterValidationResult =
validateParameters(blockParam, maybeVersionedHashParam, maybeParentBeaconBlockRootParam);
validateParameters(
blockParam,
maybeVersionedHashParam,
maybeParentBeaconBlockRootParam,
maybeRequestsParam);
if (!parameterValidationResult.isValid()) {
return new JsonRpcErrorResponse(reqId, parameterValidationResult);
}
Expand Down Expand Up @@ -183,44 +192,56 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS);
}

final Optional<List<Request>> maybeDepositRequests =
Optional.ofNullable(blockParam.getDepositRequests())
.map(ds -> ds.stream().map(DepositRequestParameter::toDeposit).collect(toList()));
if (!getDepositRequestValidator(
protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
.validateParameter(maybeDepositRequests)) {
return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_DEPOSIT_REQUEST_PARAMS);
}

final Optional<List<Request>> maybeWithdrawalRequests =
Optional.ofNullable(blockParam.getWithdrawalRequests())
.map(
withdrawalRequest ->
withdrawalRequest.stream()
.map(WithdrawalRequestParameter::toWithdrawalRequest)
.collect(toList()));
if (!getWithdrawalRequestValidator(
protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
.validateParameter(maybeWithdrawalRequests)) {
return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS);
}

final Optional<List<Request>> maybeConsolidationRequests =
Optional.ofNullable(blockParam.getConsolidationRequests())
.map(
consolidationRequest ->
consolidationRequest.stream()
.map(ConsolidationRequestParameter::toConsolidationRequest)
.collect(toList()));
if (!getConsolidationRequestValidator(
protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
.validateParameter(maybeConsolidationRequests)) {
return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_CONSOLIDATION_REQUEST_PARAMS);
}

Optional<List<Request>> maybeRequests =
RequestUtil.combine(
maybeDepositRequests, maybeWithdrawalRequests, maybeConsolidationRequests);
final Optional<List<Request>> maybeRequests;
try {
maybeRequests = extractRequests(maybeVersionedHashParam);
} catch (RuntimeException ex) {
return respondWithInvalid(
reqId,
blockParam,
mergeCoordinator.getLatestValidAncestor(blockParam.getParentHash()).orElse(null),
INVALID,
"Invalid requests");
}

// TODO re-enable validation with requests validation verifying
// that request_hash = sha256(sha256(0x00 || request_data_00) || sha256(0x01 ||
// request_data_01) || ...)
// final Optional<List<Request>> maybeDepositRequests =
// Optional.ofNullable(blockParam.getDepositRequests())
// .map(ds -> ds.stream().map(DepositRequestParameter::toDeposit).collect(toList()));
// if (!getDepositRequestValidator(
// protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
// .validateParameter(maybeDepositRequests)) {
// return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_DEPOSIT_REQUEST_PARAMS);
// }
//
// final Optional<List<Request>> maybeWithdrawalRequests =
// Optional.ofNullable(blockParam.getWithdrawalRequests())
// .map(
// withdrawalRequest ->
// withdrawalRequest.stream()
// .map(WithdrawalRequestParameter::toWithdrawalRequest)
// .collect(toList()));
// if (!getWithdrawalRequestValidator(
// protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
// .validateParameter(maybeWithdrawalRequests)) {
// return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS);
// }
//
// final Optional<List<Request>> maybeConsolidationRequests =
// Optional.ofNullable(blockParam.getConsolidationRequests())
// .map(
// consolidationRequest ->
// consolidationRequest.stream()
// .map(ConsolidationRequestParameter::toConsolidationRequest)
// .collect(toList()));
// if (!getConsolidationRequestValidator(
// protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
// .validateParameter(maybeConsolidationRequests)) {
// return new JsonRpcErrorResponse(reqId,
// RpcErrorType.INVALID_CONSOLIDATION_REQUEST_PARAMS);
// }

if (mergeContext.get().isSyncing()) {
LOG.debug("We are syncing");
Expand Down Expand Up @@ -351,8 +372,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)

final var block =
new Block(
newBlockHeader,
new BlockBody(transactions, Collections.emptyList(), maybeWithdrawals, maybeRequests));
newBlockHeader, new BlockBody(transactions, Collections.emptyList(), maybeWithdrawals));

if (maybeParentHeader.isEmpty()) {
LOG.atDebug()
Expand Down Expand Up @@ -466,7 +486,8 @@ protected EngineStatus getInvalidBlockHashStatus() {
protected ValidationResult<RpcErrorType> validateParameters(
final EnginePayloadParameter parameter,
final Optional<List<String>> maybeVersionedHashParam,
final Optional<String> maybeBeaconBlockRootParam) {
final Optional<String> maybeBeaconBlockRootParam,
final Optional<List<String>> maybeRequestsParam) {
return ValidationResult.valid();
}

Expand All @@ -490,15 +511,15 @@ protected ValidationResult<RpcErrorType> validateBlobs(

if (maybeVersionedHashes.isEmpty() && !transactionVersionedHashes.isEmpty()) {
return ValidationResult.invalid(
RpcErrorType.INVALID_VERSIONED_HASH_PARAMS,
RpcErrorType.INVALID_REQUESTS_PARAMS,
"Payload must contain versioned hashes for transactions");
}

// Validate versionedHashesParam
if (maybeVersionedHashes.isPresent()
&& !maybeVersionedHashes.get().equals(transactionVersionedHashes)) {
return ValidationResult.invalid(
RpcErrorType.INVALID_VERSIONED_HASH_PARAMS,
RpcErrorType.INVALID_REQUESTS_PARAMS,
"Versioned hashes from blob transactions do not match expected values");
}

Expand Down Expand Up @@ -562,6 +583,18 @@ private Optional<List<VersionedHash>> extractVersionedHashes(
.collect(Collectors.toList()));
}

private Optional<List<Request>> extractRequests(final Optional<List<String>> maybeRequestsParam) {
if (maybeRequestsParam.isEmpty()) {
return Optional.empty();
}

return maybeRequestsParam.map(
requests ->
IntStream.range(0, requests.size())
.mapToObj(i -> new Request(RequestType.of(i), Bytes.fromHexString(requests.get(i))))
.collect(Collectors.toList()));
}

private void logImportedBlockInfo(final Block block, final int blobCount, final double timeInS) {
final StringBuilder message = new StringBuilder();
message.append("Imported #%,d / %d tx");
Expand All @@ -572,10 +605,6 @@ private void logImportedBlockInfo(final Block block, final int blobCount, final
message.append(" / %d ws");
messageArgs.add(block.getBody().getWithdrawals().get().size());
}
if (block.getBody().getRequests().isPresent()) {
message.append(" / %d rs");
messageArgs.add(block.getBody().getRequests().get().size());
}
message.append(" / %d blobs / base fee %s / %,d (%01.1f%%) gas / (%s) in %01.3fs. Peers: %d");
messageArgs.addAll(
List.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public String getName() {
protected ValidationResult<RpcErrorType> validateParameters(
final EnginePayloadParameter payloadParameter,
final Optional<List<String>> maybeVersionedHashParam,
final Optional<String> maybeBeaconBlockRootParam) {
final Optional<String> maybeBeaconBlockRootParam,
final Optional<List<String>> maybeRequestsParam) {
if (payloadParameter.getBlobGasUsed() != null) {
return ValidationResult.invalid(
RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public String getName() {
protected ValidationResult<RpcErrorType> validateParameters(
final EnginePayloadParameter payloadParameter,
final Optional<List<String>> maybeVersionedHashParam,
final Optional<String> maybeBeaconBlockRootParam) {
final Optional<String> maybeBeaconBlockRootParam,
final Optional<List<String>> maybeRequestsParam) {
if (payloadParameter.getBlobGasUsed() == null) {
return ValidationResult.invalid(
RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public String getName() {
protected ValidationResult<RpcErrorType> validateParameters(
final EnginePayloadParameter payloadParameter,
final Optional<List<String>> maybeVersionedHashParam,
final Optional<String> maybeBeaconBlockRootParam) {
final Optional<String> maybeBeaconBlockRootParam,
final Optional<List<String>> maybeRequestsParam) {
if (payloadParameter.getBlobGasUsed() == null) {
return ValidationResult.invalid(
RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field");
Expand All @@ -69,8 +70,9 @@ protected ValidationResult<RpcErrorType> validateParameters(
return ValidationResult.invalid(
RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS,
"Missing parent beacon block root field");
} else if (payloadParameter.getDepositRequests() == null) {
return ValidationResult.invalid(RpcErrorType.INVALID_PARAMS, "Missing deposit field");
} else if (maybeRequestsParam.isEmpty()) {
return ValidationResult.invalid(
RpcErrorType.INVALID_REQUESTS_PARAMS, "Missing execution requests field");
} else {
return ValidationResult.valid();
}
Expand Down
Loading