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

Add getPayloadBodiesByRangeV1 and getPayloadBodiesByHash engine methods #4980

Merged
merged 61 commits into from
Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
b1f2abd
Add engine get payload body methods and test
wcgcyx Jan 12, 2023
4c3568e
Add header
wcgcyx Jan 12, 2023
bb5c6ed
Update result struct & add test
wcgcyx Jan 12, 2023
70ee2a5
Change constant to use upper case
wcgcyx Jan 16, 2023
0b120cb
Add PayloadBody class and withdrawals to response of methods
gfukushima Jan 23, 2023
49a3df2
Add unit tests
gfukushima Jan 23, 2023
32bf2f2
Add changelog
gfukushima Jan 23, 2023
1b4a2da
spotless
gfukushima Jan 23, 2023
7edc4d0
Add check to prevent returning trailing null results past the head
gfukushima Jan 24, 2023
1debe06
Add test to check trailing null post head scenario
gfukushima Jan 24, 2023
fdf1c4d
Split tests into pre and post shanghai
gfukushima Jan 24, 2023
fb86166
spotless
gfukushima Jan 24, 2023
9bdacea
Rename methods
gfukushima Jan 24, 2023
bfc98a0
Merge branch 'main' into add-getblock-engine-methods
gfukushima Jan 24, 2023
e43b88e
Use getName() to log method name
gfukushima Jan 24, 2023
423b66a
spotless
gfukushima Jan 24, 2023
fa72ac5
Merge branch 'main' into add-getblock-engine-methods
gfukushima Jan 24, 2023
c8aa200
Merge branch 'main' into add-getblock-engine-methods
gfukushima Jan 25, 2023
367d601
Rename variable
gfukushima Jan 25, 2023
61bce3d
Call constructor directly
gfukushima Jan 25, 2023
bccde29
Merge remote-tracking branch 'origin/add-getblock-engine-methods' int…
gfukushima Jan 25, 2023
650e70c
Merge branch 'main' into add-getblock-engine-methods
gfukushima Jan 25, 2023
663e11e
Fix ByHash json parsing
siladu Jan 25, 2023
2139828
Merge remote-tracking branch 'upstream/main' into add-getblock-engine…
siladu Jan 26, 2023
558d325
Fix json parsing again
siladu Jan 26, 2023
cfb88cc
Add check to prevent unnecessary queries
gfukushima Jan 26, 2023
f5b1d3c
Refactor method
gfukushima Jan 26, 2023
d726acb
Add new error code for EngineGetPayloadBodies methods
gfukushima Jan 27, 2023
840a59d
Add return error for request above the API limit
gfukushima Jan 27, 2023
e9d138b
Add constructor for empty response
gfukushima Jan 27, 2023
4cf2f51
add check for number of blocks requested and for requests of post head
gfukushima Jan 27, 2023
b3b7c58
Add test to check error code when request exceeds API limits
gfukushima Jan 27, 2023
334c700
add constant for max blocks allowed per request
gfukushima Jan 27, 2023
a5a2610
spotless
gfukushima Jan 27, 2023
35719c9
Merge branch 'main' into add-getblock-engine-methods
gfukushima Jan 27, 2023
e8e5a02
Fix some nits
gfukushima Jan 30, 2023
db5447f
Add invalid params check
gfukushima Jan 30, 2023
77da267
Add tests for invalid params check
gfukushima Jan 30, 2023
dbb6231
Fix test and spotless
gfukushima Jan 30, 2023
b7ae081
Merge branch 'main' into add-getblock-engine-methods
gfukushima Jan 30, 2023
2385ad7
Merge remote-tracking branch 'origin/add-getblock-engine-methods' int…
gfukushima Jan 30, 2023
08b90a9
Revert "Fix json parsing again"
gfukushima Feb 2, 2023
00a8b1b
Revert "Fix ByHash json parsing Signed-off-by: Simon Dudley <simon.du…
gfukushima Feb 2, 2023
48a8732
Use UnsignedLongParameter to cast params of the request
gfukushima Feb 2, 2023
f838d57
Add optional withdrawals to the NewPayload log (#5021)
siladu Jan 30, 2023
b3b62fd
kubernetes and errorprone - update versions (#5013)
macfarla Feb 1, 2023
9018c4b
Rename JsonRpcService to EngineJsonRpcService (#5036)
daniellehrner Feb 1, 2023
7b10e9f
Params should be single item of array type, not outer array of string…
siladu Feb 1, 2023
7554285
Add EIP-2537 (BLS12-381 curve precompiles) to Cancun (#5017)
shemnon Feb 1, 2023
6b8927e
Merge branch 'main' into add-getblock-engine-methods
gfukushima Feb 2, 2023
3e903dc
Use UnsignedLongParameter to cast params of the request
gfukushima Feb 2, 2023
f1f49bf
Add optional withdrawals to the NewPayload log (#5021)
siladu Jan 30, 2023
d4e5120
kubernetes and errorprone - update versions (#5013)
macfarla Feb 1, 2023
5700e9b
Rename JsonRpcService to EngineJsonRpcService (#5036)
daniellehrner Feb 1, 2023
24a174d
Params should be single item of array type, not outer array of string…
siladu Feb 1, 2023
9dd4185
Add EIP-2537 (BLS12-381 curve precompiles) to Cancun (#5017)
shemnon Feb 1, 2023
afed502
Convert start and count from hex to match JSON-RPC Spec standard
gfukushima Feb 3, 2023
e7b5f7c
Merge branch 'main' into add-getblock-engine-methods
gfukushima Feb 3, 2023
ab05f35
Resolve merge conflicts
gfukushima Feb 3, 2023
740c895
Merge branch 'main' into add-getblock-engine-methods
siladu Feb 7, 2023
3a644ad
Merge branch 'main' into add-getblock-engine-methods
gfukushima Feb 8, 2023
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
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

### Breaking Changes
- Add a new CLI option to limit the number of requests in a single RPC batch request. Default=1 [#4965](https://github.com/hyperledger/besu/pull/4965)

- Changed JsonRpc http service to return the error -32602 (Invalid params) with a 200 http status code
- Changed JsonRpc http service to return the error -32602 (Invalid params) with a 200 http status code [#4967](https://github.com/hyperledger/besu/pull/4967)

### Additions and Improvements
- Added option to evm CLI tool to allow code execution at specific forks [#4913](https://github.com/hyperledger/besu/pull/4913)
- Improve get account performance by using the world state updater cache [#4897](https://github.com/hyperledger/besu/pull/4897)
- Add implementation for eth_createAccessList RPC method [#4942](https://github.com/hyperledger/besu/pull/4942)
- Add implementation for engine_getPayloadBodiesByRangeV1 and engine_getPayloadBodiesByHashV1 [#4980](https://github.com/hyperledger/besu/pull/4980)

### Bug Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public enum RpcMethod {
ENGINE_FORKCHOICE_UPDATED_V1("engine_forkchoiceUpdatedV1"),
ENGINE_FORKCHOICE_UPDATED_V2("engine_forkchoiceUpdatedV2"),
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION("engine_exchangeTransitionConfigurationV1"),
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1("engine_getPayloadBodiesByHashV1"),
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1("engine_getPayloadBodiesByRangeV1"),

GOQUORUM_ETH_GET_QUORUM_PAYLOAD("eth_getQuorumPayload"),
GOQUORUM_STORE_RAW("goquorum_storeRaw"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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.methods.engine;

import static org.hyperledger.besu.util.Slf4jLambdaHelper.traceLambda;

import org.hyperledger.besu.datatypes.Hash;
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.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.results.BlockResultFactory;
import org.hyperledger.besu.ethereum.chain.Blockchain;

import java.util.Arrays;
import java.util.stream.Collectors;

import io.vertx.core.Vertx;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EngineGetPayloadBodiesByHashV1 extends ExecutionEngineJsonRpcMethod {
private static final Logger LOG = LoggerFactory.getLogger(EngineGetPayloadBodiesByHashV1.class);
private final BlockResultFactory blockResultFactory;

public EngineGetPayloadBodiesByHashV1(
final Vertx vertx,
final ProtocolContext protocolContext,
final BlockResultFactory blockResultFactory,
final EngineCallListener engineCallListener) {
super(vertx, protocolContext, engineCallListener);
this.blockResultFactory = blockResultFactory;
}

@Override
public String getName() {
return RpcMethod.ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1.getMethodName();
}

@Override
public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) {
engineCallListener.executionEngineCalled();

final Hash[] blockHashes = request.getRequiredParameter(0, Hash[].class);

traceLambda(
LOG, "EngineGetPayloadBodiesByHashV1 parameters: blockHashes {}", () -> blockHashes);

final Blockchain blockchain = protocolContext.getBlockchain();
return new JsonRpcSuccessResponse(
request.getRequest().getId(),
blockResultFactory.payloadBodiesCompleteV1(
jframe marked this conversation as resolved.
Show resolved Hide resolved
Arrays.stream(blockHashes).map(blockchain::getBlockBody).collect(Collectors.toList())));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* 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.methods.engine;

import static org.hyperledger.besu.util.Slf4jLambdaHelper.traceLambda;

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.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.results.BlockResultFactory;
import org.hyperledger.besu.ethereum.chain.Blockchain;

import java.util.stream.Collectors;
import java.util.stream.LongStream;

import io.vertx.core.Vertx;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EngineGetPayloadBodiesByRangeV1 extends ExecutionEngineJsonRpcMethod {
private static final Logger LOG = LoggerFactory.getLogger(EngineGetPayloadBodiesByRangeV1.class);
private final BlockResultFactory blockResultFactory;

public EngineGetPayloadBodiesByRangeV1(
final Vertx vertx,
final ProtocolContext protocolContext,
final BlockResultFactory blockResultFactory,
final EngineCallListener engineCallListener) {
super(vertx, protocolContext, engineCallListener);
this.blockResultFactory = blockResultFactory;
}

@Override
public String getName() {
return RpcMethod.ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1.getMethodName();
}

@Override
public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) {
engineCallListener.executionEngineCalled();

final long startBlockNumber = request.getRequiredParameter(0, Long.class);
final long count = request.getRequiredParameter(1, Long.class);

traceLambda(
LOG,
"EngineGetPayloadBodiesByRangeV1 parameters: start block number {} count {}",
gfukushima marked this conversation as resolved.
Show resolved Hide resolved
() -> startBlockNumber,
() -> count);

final Blockchain blockchain = protocolContext.getBlockchain();

final long latestKnownBlockNumber = blockchain.getChainHeadBlockNumber();
final long upperBound = startBlockNumber + count;
final long finalBlockNumber =
latestKnownBlockNumber < upperBound ? latestKnownBlockNumber + 1 : upperBound;

return new JsonRpcSuccessResponse(
request.getRequest().getId(),
blockResultFactory.payloadBodiesCompleteV1(
LongStream.range(startBlockNumber, finalBlockNumber)
.mapToObj(
blockNumber ->
blockchain
.getBlockHashByNumber(blockNumber)
.flatMap(blockchain::getBlockBody))
siladu marked this conversation as resolved.
Show resolved Hide resolved
.collect(Collectors.toList())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,19 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;

import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetPayloadBodiesResultV1.PayloadBody;
import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata;
import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockValueCalculator;
import org.hyperledger.besu.ethereum.core.BlockWithReceipts;
import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.fasterxml.jackson.databind.JsonNode;
Expand Down Expand Up @@ -114,6 +117,15 @@ public EngineGetPayloadResultV2 payloadTransactionCompleteV2(
Quantity.create(blockValue));
}

public EngineGetPayloadBodiesResultV1 payloadBodiesCompleteV1(
final List<Optional<BlockBody>> blockBodies) {
final List<PayloadBody> payloadBodies =
blockBodies.stream()
.map(maybeBody -> maybeBody.map(blockBody -> new PayloadBody(blockBody)).orElse(null))
siladu marked this conversation as resolved.
Show resolved Hide resolved
.collect(Collectors.toList());
return new EngineGetPayloadBodiesResultV1(payloadBodies);
}

public BlockResult transactionHash(final BlockWithMetadata<Hash, Hash> blockWithMetadata) {
return transactionHash(blockWithMetadata, false);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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.results;

import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;

import java.util.List;
import java.util.stream.Collectors;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonValue;
import org.apache.tuweni.bytes.Bytes;

@JsonPropertyOrder({"payloadBodies"})
public class EngineGetPayloadBodiesResultV1 {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Not sure it makes sense for this outer result type to be V1...the type in the spec that is versioned is ExecutionPayloadBodyV1 which you have below as PayloadBody...if anything then that should be versioned, but I'm thinking avoid versioning unless we have to.

The only engine api result class that's versioned is EngineGetPayloadResultV1/V2 are versioned because they are different data shapes and we need to distinguish. I am having second thoughts about those names now though.

private final List<PayloadBody> payloadBodies;

public EngineGetPayloadBodiesResultV1(final List<PayloadBody> payloadBody) {
this.payloadBodies = payloadBody;
}

@JsonValue
public List<PayloadBody> getPayloadBodies() {
return payloadBodies;
}

public static class PayloadBody {
private final List<String> transactions;
private final List<WithdrawalParameter> withdrawals;

public PayloadBody(final BlockBody blockBody) {
this.transactions =
blockBody.getTransactions().stream()
.map(TransactionEncoder::encodeOpaqueBytes)
.map(Bytes::toHexString)
.collect(Collectors.toList());
this.withdrawals =
blockBody
.getWithdrawals()
.map(
ws ->
ws.stream()
.map(WithdrawalParameter::fromWithdrawal)
.collect(Collectors.toList()))
.orElse(null);
}

@JsonGetter(value = "transactions")
public List<String> getTransactions() {
return transactions;
}

@JsonGetter(value = "withdrawals")
public List<WithdrawalParameter> getWithdrawals() {
return withdrawals;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineExchangeTransitionConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV1;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV2;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByHashV1;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByRangeV1;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV1;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV2;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineNewPayloadV1;
Expand Down Expand Up @@ -112,7 +114,11 @@ protected Map<String, JsonRpcMethod> create() {
mergeCoordinator.get(),
engineQosTimer),
new EngineExchangeTransitionConfiguration(
consensusEngineServer, protocolContext, engineQosTimer));
consensusEngineServer, protocolContext, engineQosTimer),
new EngineGetPayloadBodiesByHashV1(
consensusEngineServer, protocolContext, blockResultFactory, engineQosTimer),
new EngineGetPayloadBodiesByRangeV1(
consensusEngineServer, protocolContext, blockResultFactory, engineQosTimer));
} else {
return mapOf(
new EngineExchangeTransitionConfiguration(
Expand Down
Loading