Skip to content

Commit

Permalink
make engine api usable without a merge config.
Browse files Browse the repository at this point in the history
leaves the door open to supporting the engine api with other MiningCoordinators, but disables all but engine_exchangeTransitionConfiguration in the absence of mergeCoordinator

Signed-off-by: garyschulte <garyschulte@gmail.com>
  • Loading branch information
garyschulte committed Jul 28, 2022
1 parent 9c2e0eb commit d86e2c6
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 27 deletions.
2 changes: 1 addition & 1 deletion besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ public RunnerBuilder jsonRpcConfiguration(final JsonRpcConfiguration jsonRpcConf

public RunnerBuilder engineJsonRpcConfiguration(
final JsonRpcConfiguration engineJsonRpcConfiguration) {
this.engineJsonRpcConfiguration = Optional.of(engineJsonRpcConfiguration);
this.engineJsonRpcConfiguration = Optional.ofNullable(engineJsonRpcConfiguration);
return this;
}

Expand Down
8 changes: 5 additions & 3 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -1930,9 +1930,11 @@ private void configure() throws Exception {
jsonRpcConfiguration =
jsonRpcConfiguration(
jsonRPCHttpOptionGroup.rpcHttpPort, jsonRPCHttpOptionGroup.rpcHttpApis, hostsAllowlist);
engineJsonRpcConfiguration =
createEngineJsonRpcConfiguration(
engineRPCOptionGroup.engineRpcPort, engineRPCOptionGroup.engineHostsAllowlist);
if (isEngineApiEnabled()) {
engineJsonRpcConfiguration =
createEngineJsonRpcConfiguration(
engineRPCOptionGroup.engineRpcPort, engineRPCOptionGroup.engineHostsAllowlist);
}
p2pTLSConfiguration = p2pTLSConfigOptions.p2pTLSConfiguration(commandLine);
graphQLConfiguration = graphQLConfiguration();
webSocketConfiguration =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ PayloadIdentifier preparePayload(
final Bytes32 random,
final Address feeRecipient);

@Override
default boolean isCompatibleWithEngineApi() {
return true;
}

Result rememberBlock(final Block block);

Result validateBlock(final Block block);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

Expand All @@ -40,13 +41,13 @@ public enum EngineStatus {
public static final long ENGINE_API_LOGGING_THRESHOLD = 60000L;
private final Vertx syncVertx;
private static final Logger LOG = LoggerFactory.getLogger(ExecutionEngineJsonRpcMethod.class);
protected final MergeContext mergeContext;
protected final Optional<MergeContext> mergeContext;
protected final ProtocolContext protocolContext;

protected ExecutionEngineJsonRpcMethod(final Vertx vertx, final ProtocolContext protocolContext) {
this.syncVertx = vertx;
this.protocolContext = protocolContext;
this.mergeContext = protocolContext.getConsensusContext(MergeContext.class);
this.mergeContext = protocolContext.safeConsensusContext(MergeContext.class);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,23 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineExchangeTransitionConfigurationResult;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Difficulty;

import java.util.Optional;

import io.vertx.core.Vertx;
import io.vertx.core.json.Json;
import org.apache.tuweni.units.bigints.UInt256;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

// use (2^256 - 2^10) if engine is enabled in the absence of a TTD configuration
static final Difficulty FALLBACK_TTD_DEFAULT =
Difficulty.MAX_VALUE.subtract(UInt256.valueOf(1024L));
static final long QOS_TIMEOUT_MILLIS = 120000L;

private final QosTimer qosTimer;
Expand Down Expand Up @@ -76,11 +81,12 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
"received transitionConfiguration: {}",
() -> Json.encodePrettily(remoteTransitionConfiguration));

final Optional<BlockHeader> maybeTerminalPoWBlockHeader = mergeContext.getTerminalPoWBlock();
final Optional<BlockHeader> maybeTerminalPoWBlockHeader =
mergeContext.flatMap(c -> c.getTerminalPoWBlock());

final EngineExchangeTransitionConfigurationResult localTransitionConfiguration =
new EngineExchangeTransitionConfigurationResult(
mergeContext.getTerminalTotalDifficulty(),
mergeContext.map(c -> c.getTerminalTotalDifficulty()).orElse(FALLBACK_TTD_DEFAULT),
maybeTerminalPoWBlockHeader.map(BlockHeader::getHash).orElse(Hash.ZERO),
maybeTerminalPoWBlockHeader.map(BlockHeader::getNumber).orElse(0L));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,12 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
Optional.ofNullable(forkChoice.getFinalizedBlockHash())
.filter(finalized -> !finalized.isZero());

mergeContext.fireNewUnverifiedForkchoiceMessageEvent(
forkChoice.getHeadBlockHash(), maybeFinalizedHash, forkChoice.getSafeBlockHash());
mergeContext.ifPresent(
c ->
c.fireNewUnverifiedForkchoiceMessageEvent(
forkChoice.getHeadBlockHash(), maybeFinalizedHash, forkChoice.getSafeBlockHash()));

if (mergeContext.isSyncing()) {
if (mergeContext.map(c -> c.isSyncing()).orElse(Boolean.TRUE)) {
return syncingResponse(requestId, forkChoice);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public String getName() {
public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) {
final PayloadIdentifier payloadId = request.getRequiredParameter(0, PayloadIdentifier.class);

final Optional<Block> block = mergeContext.retrieveBlockById(payloadId);
final Optional<Block> block = mergeContext.flatMap(c -> c.retrieveBlockById(payloadId));
if (block.isPresent()) {
var proposal = block.get();
var proposalHeader = proposal.getHeader();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
final var block =
new Block(newBlockHeader, new BlockBody(transactions, Collections.emptyList()));

if (mergeContext.isSyncing() || parentHeader.isEmpty()) {
if (mergeContext.map(c -> c.isSyncing()).orElse(Boolean.TRUE) || parentHeader.isEmpty()) {
LOG.debug(
"isSyncing: {} parentHeaderMissing: {}, adding {} to backwardsync",
mergeContext.isSyncing(),
mergeContext.map(c -> c.isSyncing()).orElse(null),
parentHeader.isEmpty(),
block.getHash());
mergeCoordinator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;

import java.util.Map;
import java.util.Optional;

import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
Expand All @@ -34,12 +35,16 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {

private final BlockResultFactory blockResultFactory = new BlockResultFactory();

private final MergeMiningCoordinator mergeCoordinator;
private final Optional<MergeMiningCoordinator> mergeCoordinator;
private final ProtocolContext protocolContext;

ExecutionEngineJsonRpcMethods(
final MiningCoordinator miningCoordinator, final ProtocolContext protocolContext) {
this.mergeCoordinator = (MergeMiningCoordinator) miningCoordinator;
this.mergeCoordinator =
Optional.ofNullable(miningCoordinator)
.filter(mc -> mc.isCompatibleWithEngineApi())
.map(MergeMiningCoordinator.class::cast);

this.protocolContext = protocolContext;
}

Expand All @@ -51,10 +56,14 @@ protected String getApiGroup() {
@Override
protected Map<String, JsonRpcMethod> create() {
Vertx syncVertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(1));
return mapOf(
new EngineGetPayload(syncVertx, protocolContext, blockResultFactory),
new EngineNewPayload(syncVertx, protocolContext, mergeCoordinator),
new EngineForkchoiceUpdated(syncVertx, protocolContext, mergeCoordinator),
new EngineExchangeTransitionConfiguration(syncVertx, protocolContext));
if (mergeCoordinator.isPresent()) {
return mapOf(
new EngineGetPayload(syncVertx, protocolContext, blockResultFactory),
new EngineNewPayload(syncVertx, protocolContext, mergeCoordinator.get()),
new EngineForkchoiceUpdated(syncVertx, protocolContext, mergeCoordinator.get()),
new EngineExchangeTransitionConfiguration(syncVertx, protocolContext));
} else {
return mapOf(new EngineExchangeTransitionConfiguration(syncVertx, protocolContext));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;

import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager;
Expand Down Expand Up @@ -95,6 +94,7 @@ public Map<String, JsonRpcMethod> methods(
blockchainQueries, protocolSchedule, metricsSystem, transactionPool, dataDir),
new EeaJsonRpcMethods(
blockchainQueries, protocolSchedule, transactionPool, privacyParameters),
new ExecutionEngineJsonRpcMethods(miningCoordinator, protocolContext),
new GoQuorumJsonRpcPrivacyMethods(
blockchainQueries, protocolSchedule, transactionPool, privacyParameters),
new EthJsonRpcMethods(
Expand Down Expand Up @@ -127,11 +127,6 @@ public Map<String, JsonRpcMethod> methods(
new TxPoolJsonRpcMethods(transactionPool),
new PluginsJsonRpcMethods(namedPlugins));

if (MergeConfigOptions.isMergeEnabled()) {
enabled.putAll(
new ExecutionEngineJsonRpcMethods(miningCoordinator, protocolContext).create(rpcApis));
}

for (final JsonRpcMethods apiGroup : availableApiGroups) {
enabled.putAll(apiGroup.create(rpcApis));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineExchangeTransitionConfiguration.FALLBACK_TTD_DEFAULT;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
Expand Down Expand Up @@ -114,6 +115,21 @@ public void shouldReturnZerosOnTerminalPoWBlockHeaderEmpty() {
assertThat(result.getTerminalBlockNumber()).isEqualTo(0L);
}

@Test
public void shouldReturnDefaultOnNoTerminalTotalDifficultyConfigured() {
when(mergeContext.getTerminalPoWBlock()).thenReturn(Optional.empty());

var response =
resp(
new EngineExchangeTransitionConfigurationParameter(
"0", Hash.ZERO.toHexString(), new UnsignedLongParameter(0L)));

var result = fromSuccessResp(response);
assertThat(result.getTerminalTotalDifficulty()).isEqualTo(FALLBACK_TTD_DEFAULT);
assertThat(result.getTerminalBlockHash()).isEqualTo(Hash.ZERO);
assertThat(result.getTerminalBlockNumber()).isEqualTo(0L);
}

@Test
public void shouldReturnConfigurationOnConfigurationMisMatch() {
final BlockHeader fakeBlockHeader = createBlockHeader(Hash.fromHexStringLenient("0x01"), 42);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,8 @@ Optional<Block> createBlock(
default void addEthHashObserver(final PoWObserver observer) {}

void changeTargetGasLimit(final Long targetGasLimit);

default boolean isCompatibleWithEngineApi() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;

import java.util.Optional;

/**
* Holds the mutable state used to track the current context of the protocol. This is primarily the
* blockchain and world state archive, but can also hold arbitrary context required by a particular
Expand Down Expand Up @@ -59,4 +61,10 @@ public WorldStateArchive getWorldStateArchive() {
public <C extends ConsensusContext> C getConsensusContext(final Class<C> klass) {
return consensusContext.as(klass);
}

public <C extends ConsensusContext> Optional<C> safeConsensusContext(final Class<C> klass) {
return Optional.ofNullable(consensusContext)
.filter(c -> klass.isAssignableFrom(c.getClass()))
.map(klass::cast);
}
}

0 comments on commit d86e2c6

Please sign in to comment.