mirror of https://github.com/hyperledger/besu
commit
b2e1069f31
@ -0,0 +1,76 @@ |
||||
/* |
||||
* Copyright contributors to 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.tests.acceptance.plugins; |
||||
|
||||
import org.hyperledger.besu.plugin.BesuContext; |
||||
import org.hyperledger.besu.plugin.BesuPlugin; |
||||
import org.hyperledger.besu.plugin.services.MetricsSystem; |
||||
import org.hyperledger.besu.plugin.services.metrics.MetricCategory; |
||||
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry; |
||||
|
||||
import java.util.Locale; |
||||
import java.util.Optional; |
||||
|
||||
import com.google.auto.service.AutoService; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
@AutoService(BesuPlugin.class) |
||||
public class TestMetricsPlugin implements BesuPlugin { |
||||
private static final Logger LOG = LoggerFactory.getLogger(TestMetricsPlugin.class); |
||||
private BesuContext besuContext; |
||||
|
||||
@Override |
||||
public void register(final BesuContext context) { |
||||
LOG.info("Registering TestMetricsPlugin"); |
||||
besuContext = context; |
||||
context |
||||
.getService(MetricCategoryRegistry.class) |
||||
.orElseThrow() |
||||
.addMetricCategory(TestMetricCategory.TEST_METRIC_CATEGORY); |
||||
} |
||||
|
||||
@Override |
||||
public void start() { |
||||
LOG.info("Starting TestMetricsPlugin"); |
||||
besuContext |
||||
.getService(MetricsSystem.class) |
||||
.orElseThrow() |
||||
.createGauge( |
||||
TestMetricCategory.TEST_METRIC_CATEGORY, |
||||
"test_metric", |
||||
"Returns 1 on succes", |
||||
() -> 1.0); |
||||
} |
||||
|
||||
@Override |
||||
public void stop() { |
||||
LOG.info("Stopping TestMetricsPlugin"); |
||||
} |
||||
|
||||
public enum TestMetricCategory implements MetricCategory { |
||||
TEST_METRIC_CATEGORY; |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return name().toLowerCase(Locale.ROOT); |
||||
} |
||||
|
||||
@Override |
||||
public Optional<String> getApplicationPrefix() { |
||||
return Optional.of("plugin_test_"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,73 @@ |
||||
/* |
||||
* Copyright contributors to 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.tests.acceptance.plugins; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.hyperledger.besu.tests.acceptance.plugins.TestMetricsPlugin.TestMetricCategory.TEST_METRIC_CATEGORY; |
||||
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; |
||||
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; |
||||
import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; |
||||
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeConfigurationBuilder; |
||||
|
||||
import java.io.IOException; |
||||
import java.net.URI; |
||||
import java.net.http.HttpClient; |
||||
import java.net.http.HttpRequest; |
||||
import java.net.http.HttpResponse; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
public class MetricsPluginTest extends AcceptanceTestBase { |
||||
private BesuNode node; |
||||
private MetricsConfiguration metricsConfiguration; |
||||
|
||||
@BeforeEach |
||||
public void setUp() throws Exception { |
||||
metricsConfiguration = |
||||
MetricsConfiguration.builder() |
||||
.enabled(true) |
||||
.port(0) |
||||
.metricCategories(Set.of(TEST_METRIC_CATEGORY)) |
||||
.build(); |
||||
node = |
||||
besu.create( |
||||
new BesuNodeConfigurationBuilder() |
||||
.name("node1") |
||||
.plugins(List.of("testPlugins")) |
||||
.metricsConfiguration(metricsConfiguration) |
||||
.build()); |
||||
|
||||
cluster.start(node); |
||||
} |
||||
|
||||
@Test |
||||
public void metricCategoryAdded() throws IOException, InterruptedException { |
||||
final var httpClient = HttpClient.newHttpClient(); |
||||
final var req = HttpRequest.newBuilder(URI.create(node.metricsHttpUrl().get())).build(); |
||||
final var resp = httpClient.send(req, HttpResponse.BodyHandlers.ofLines()); |
||||
assertThat(resp.statusCode()).isEqualTo(200); |
||||
final var foundMetric = |
||||
resp.body() |
||||
.filter( |
||||
line -> line.startsWith(TEST_METRIC_CATEGORY.getApplicationPrefix().orElseThrow())) |
||||
.findFirst() |
||||
.orElseThrow(); |
||||
assertThat(foundMetric).endsWith("1.0"); |
||||
} |
||||
} |
@ -1,73 +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.cli.converter; |
||||
|
||||
import org.hyperledger.besu.plugin.services.metrics.MetricCategory; |
||||
|
||||
import java.util.EnumSet; |
||||
import java.util.HashMap; |
||||
import java.util.Locale; |
||||
import java.util.Map; |
||||
|
||||
import com.google.common.annotations.VisibleForTesting; |
||||
import picocli.CommandLine; |
||||
|
||||
/** The Metric category converter for CLI options. */ |
||||
public class MetricCategoryConverter implements CommandLine.ITypeConverter<MetricCategory> { |
||||
|
||||
private final Map<String, MetricCategory> metricCategories = new HashMap<>(); |
||||
|
||||
/** Default Constructor. */ |
||||
public MetricCategoryConverter() {} |
||||
|
||||
@Override |
||||
public MetricCategory convert(final String value) { |
||||
final MetricCategory category = metricCategories.get(value); |
||||
if (category == null) { |
||||
throw new IllegalArgumentException("Unknown category: " + value); |
||||
} |
||||
return category; |
||||
} |
||||
|
||||
/** |
||||
* Add Metrics categories. |
||||
* |
||||
* @param <T> the type parameter |
||||
* @param categoryEnum the category enum |
||||
*/ |
||||
public <T extends Enum<T> & MetricCategory> void addCategories(final Class<T> categoryEnum) { |
||||
EnumSet.allOf(categoryEnum) |
||||
.forEach(category -> metricCategories.put(category.name(), category)); |
||||
} |
||||
|
||||
/** |
||||
* Add registry category. |
||||
* |
||||
* @param metricCategory the metric category |
||||
*/ |
||||
public void addRegistryCategory(final MetricCategory metricCategory) { |
||||
metricCategories.put(metricCategory.getName().toUpperCase(Locale.ROOT), metricCategory); |
||||
} |
||||
|
||||
/** |
||||
* Gets metric categories. |
||||
* |
||||
* @return the metric categories |
||||
*/ |
||||
@VisibleForTesting |
||||
Map<String, MetricCategory> getMetricCategories() { |
||||
return metricCategories; |
||||
} |
||||
} |
@ -1,149 +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.cli.subcommands; |
||||
|
||||
import static org.hyperledger.besu.cli.subcommands.RetestethSubCommand.COMMAND_NAME; |
||||
|
||||
import org.hyperledger.besu.BesuInfo; |
||||
import org.hyperledger.besu.cli.DefaultCommandValues; |
||||
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; |
||||
import org.hyperledger.besu.cli.options.stable.LoggingLevelOption; |
||||
import org.hyperledger.besu.cli.util.VersionProvider; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; |
||||
import org.hyperledger.besu.ethereum.retesteth.RetestethConfiguration; |
||||
import org.hyperledger.besu.ethereum.retesteth.RetestethService; |
||||
import org.hyperledger.besu.util.LogConfigurator; |
||||
|
||||
import java.net.InetAddress; |
||||
import java.nio.file.Path; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import picocli.CommandLine.Command; |
||||
import picocli.CommandLine.Mixin; |
||||
import picocli.CommandLine.Option; |
||||
|
||||
/** Subcommand to run a Retesteth compatible server for reference tests. */ |
||||
@Command( |
||||
name = COMMAND_NAME, |
||||
description = "Run a Retesteth compatible server for reference tests.", |
||||
mixinStandardHelpOptions = true, |
||||
versionProvider = VersionProvider.class) |
||||
@SuppressWarnings("unused") |
||||
public class RetestethSubCommand implements Runnable { |
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RetestethSubCommand.class); |
||||
|
||||
/** The constant COMMAND_NAME. */ |
||||
public static final String COMMAND_NAME = "retesteth"; |
||||
|
||||
/** |
||||
* Using a distinct port for retesteth will result in less testing collisions and accidental RPC |
||||
* calls. This is <code>0xba5e</code> in hex, a hex speak play on the english translation of |
||||
* "Besu." |
||||
*/ |
||||
public static final int RETESTETH_PORT = 47710; |
||||
|
||||
@Option( |
||||
names = {"--data-path"}, |
||||
paramLabel = DefaultCommandValues.MANDATORY_PATH_FORMAT_HELP, |
||||
description = "The path to Besu data directory (default: ${DEFAULT-VALUE})") |
||||
private final Path dataPath = DefaultCommandValues.getDefaultBesuDataPath(this); |
||||
|
||||
@Mixin private LoggingLevelOption loggingLevelOption; |
||||
|
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||
@Option( |
||||
names = {"--rpc-http-host"}, |
||||
paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP, |
||||
description = "Host for Retesteth JSON-RPC HTTP to listen on (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
private String rpcHttpHost = autoDiscoverDefaultIP().getHostAddress(); |
||||
|
||||
@Option( |
||||
names = {"--rpc-http-port"}, |
||||
paramLabel = DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP, |
||||
description = "Port for Retesteth JSON-RPC HTTP to listen on (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
private final Integer rpcHttpPort = RETESTETH_PORT; |
||||
|
||||
@Option( |
||||
names = {"--host-allowlist", "--host-whitelist"}, |
||||
paramLabel = "<hostname>[,<hostname>...]... or * or all", |
||||
description = |
||||
"Comma separated list of hostnames to allow for RPC access, or * to accept any host (default: ${DEFAULT-VALUE})", |
||||
defaultValue = "localhost,127.0.0.1") |
||||
private final JsonRPCAllowlistHostsProperty hostsAllowlist = new JsonRPCAllowlistHostsProperty(); |
||||
|
||||
private InetAddress autoDiscoveredDefaultIP; |
||||
|
||||
/** Default Constructor. */ |
||||
public RetestethSubCommand() {} |
||||
|
||||
// Used to discover the default IP of the client.
|
||||
// Loopback IP is used by default as this is how smokeTests require it to be
|
||||
// and it's probably a good security behaviour to default only on the localhost.
|
||||
private InetAddress autoDiscoverDefaultIP() { |
||||
|
||||
if (autoDiscoveredDefaultIP != null) { |
||||
return autoDiscoveredDefaultIP; |
||||
} |
||||
|
||||
autoDiscoveredDefaultIP = InetAddress.getLoopbackAddress(); |
||||
|
||||
return autoDiscoveredDefaultIP; |
||||
} |
||||
|
||||
private void prepareLogging() { |
||||
// set log level per CLI flags
|
||||
final String logLevel = loggingLevelOption.getLogLevel(); |
||||
if (logLevel != null) { |
||||
System.out.println("Setting logging level to " + logLevel); |
||||
LogConfigurator.setLevel("", logLevel); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void run() { |
||||
prepareLogging(); |
||||
|
||||
final RetestethConfiguration retestethConfiguration = new RetestethConfiguration(dataPath); |
||||
final JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault(); |
||||
jsonRpcConfiguration.setHost(rpcHttpHost); |
||||
jsonRpcConfiguration.setPort(rpcHttpPort); |
||||
jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist); |
||||
|
||||
final RetestethService retestethService = |
||||
new RetestethService(BesuInfo.version(), retestethConfiguration, jsonRpcConfiguration); |
||||
|
||||
Runtime.getRuntime() |
||||
.addShutdownHook( |
||||
new Thread( |
||||
() -> { |
||||
try { |
||||
retestethService.close(); |
||||
LogConfigurator.shutdown(); |
||||
} catch (final Exception e) { |
||||
LOG.error("Failed to stop Besu Retesteth"); |
||||
} |
||||
})); |
||||
retestethService.start(); |
||||
try { |
||||
Thread.sleep(Long.MAX_VALUE); // Is there a better way?
|
||||
} catch (final InterruptedException e) { |
||||
// e.printStackTrace();
|
||||
} |
||||
} |
||||
} |
@ -1,63 +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.cli.converter; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.hyperledger.besu.plugin.services.metrics.MetricCategory; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
|
||||
@ExtendWith(MockitoExtension.class) |
||||
public class MetricCategoryConverterTest { |
||||
|
||||
private MetricCategoryConverter metricCategoryConverter; |
||||
|
||||
@Mock MetricCategory metricCategory; |
||||
|
||||
@BeforeEach |
||||
public void setUp() { |
||||
metricCategoryConverter = new MetricCategoryConverter(); |
||||
} |
||||
|
||||
@Test |
||||
public void convertShouldFailIfValueNotRegistered() { |
||||
assertThatExceptionOfType(IllegalArgumentException.class) |
||||
.isThrownBy(() -> metricCategoryConverter.convert("notRegistered")); |
||||
} |
||||
|
||||
@Test |
||||
public void addRegistryCategoryShouldUppercaseInputValues() { |
||||
when(metricCategory.getName()).thenReturn("testcat"); |
||||
metricCategoryConverter.addRegistryCategory(metricCategory); |
||||
when(metricCategory.getName()).thenReturn("tesTCat2"); |
||||
metricCategoryConverter.addRegistryCategory(metricCategory); |
||||
|
||||
final boolean containsLowercase = |
||||
metricCategoryConverter.getMetricCategories().keySet().stream() |
||||
.anyMatch(testString -> testString.chars().anyMatch(Character::isLowerCase)); |
||||
|
||||
assertThat(containsLowercase).isFalse(); |
||||
assertThat(metricCategoryConverter.getMetricCategories().size()).isEqualTo(2); |
||||
assertThat(metricCategoryConverter.getMetricCategories().keySet()) |
||||
.containsExactlyInAnyOrder("TESTCAT", "TESTCAT2"); |
||||
} |
||||
} |
@ -0,0 +1,110 @@ |
||||
/* |
||||
* 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.ethereum.api.handlers; |
||||
|
||||
import static org.mockito.ArgumentMatchers.any; |
||||
import static org.mockito.ArgumentMatchers.anyInt; |
||||
import static org.mockito.ArgumentMatchers.anyLong; |
||||
import static org.mockito.ArgumentMatchers.contains; |
||||
import static org.mockito.ArgumentMatchers.eq; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.context.ContextKey; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.execution.JsonRpcExecutor; |
||||
|
||||
import io.netty.handler.codec.http.HttpResponseStatus; |
||||
import io.opentelemetry.api.trace.Tracer; |
||||
import io.vertx.core.Handler; |
||||
import io.vertx.core.Vertx; |
||||
import io.vertx.core.http.HttpServerResponse; |
||||
import io.vertx.ext.web.RoutingContext; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.mockito.ArgumentCaptor; |
||||
|
||||
class JsonRpcExecutorHandlerTest { |
||||
|
||||
private JsonRpcExecutor mockExecutor; |
||||
private Tracer mockTracer; |
||||
private JsonRpcConfiguration mockConfig; |
||||
private RoutingContext mockContext; |
||||
private Vertx mockVertx; |
||||
private HttpServerResponse mockResponse; |
||||
|
||||
@BeforeEach |
||||
void setUp() { |
||||
mockExecutor = mock(JsonRpcExecutor.class); |
||||
mockTracer = mock(Tracer.class); |
||||
mockConfig = mock(JsonRpcConfiguration.class); |
||||
mockContext = mock(RoutingContext.class); |
||||
mockVertx = mock(Vertx.class); |
||||
mockResponse = mock(HttpServerResponse.class); |
||||
|
||||
when(mockContext.vertx()).thenReturn(mockVertx); |
||||
when(mockContext.response()).thenReturn(mockResponse); |
||||
when(mockResponse.ended()).thenReturn(false); |
||||
when(mockResponse.setStatusCode(anyInt())).thenReturn(mockResponse); |
||||
} |
||||
|
||||
@Test |
||||
void testTimeoutHandling() { |
||||
// Arrange
|
||||
Handler<RoutingContext> handler = |
||||
JsonRpcExecutorHandler.handler(mockExecutor, mockTracer, mockConfig); |
||||
ArgumentCaptor<Long> delayCaptor = ArgumentCaptor.forClass(Long.class); |
||||
@SuppressWarnings("unchecked") |
||||
ArgumentCaptor<Handler<Long>> timerHandlerCaptor = ArgumentCaptor.forClass(Handler.class); |
||||
|
||||
when(mockContext.get(eq(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()))).thenReturn("{}"); |
||||
when(mockVertx.setTimer(delayCaptor.capture(), timerHandlerCaptor.capture())).thenReturn(1L); |
||||
when(mockContext.get("timerId")).thenReturn(1L); |
||||
|
||||
// Act
|
||||
handler.handle(mockContext); |
||||
|
||||
// Assert
|
||||
verify(mockVertx).setTimer(eq(30000L), any()); |
||||
|
||||
// Simulate timeout
|
||||
timerHandlerCaptor.getValue().handle(1L); |
||||
|
||||
// Verify timeout handling
|
||||
verify(mockResponse, times(1)) |
||||
.setStatusCode(eq(HttpResponseStatus.REQUEST_TIMEOUT.code())); // Expect 408 Request Timeout
|
||||
verify(mockResponse, times(1)).end(contains("Timeout expired")); |
||||
verify(mockVertx, times(1)).cancelTimer(1L); |
||||
} |
||||
|
||||
@Test |
||||
void testCancelTimerOnSuccessfulExecution() { |
||||
// Arrange
|
||||
Handler<RoutingContext> handler = |
||||
JsonRpcExecutorHandler.handler(mockExecutor, mockTracer, mockConfig); |
||||
when(mockContext.get(eq(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()))).thenReturn("{}"); |
||||
when(mockVertx.setTimer(anyLong(), any())).thenReturn(1L); |
||||
when(mockContext.get("timerId")).thenReturn(1L); |
||||
|
||||
// Act
|
||||
handler.handle(mockContext); |
||||
|
||||
// Assert
|
||||
verify(mockVertx).setTimer(anyLong(), any()); |
||||
verify(mockVertx).cancelTimer(1L); |
||||
} |
||||
} |
@ -0,0 +1,100 @@ |
||||
/* |
||||
* 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.ethereum.components; |
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions; |
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager; |
||||
import org.hyperledger.besu.ethereum.core.MiningParameters; |
||||
import org.hyperledger.besu.ethereum.core.PrivacyParameters; |
||||
import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule; |
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; |
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; |
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; |
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration; |
||||
import org.hyperledger.besu.plugin.services.MetricsSystem; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.util.Optional; |
||||
import javax.inject.Singleton; |
||||
|
||||
import dagger.Module; |
||||
import dagger.Provides; |
||||
|
||||
/** Provides the protocol schedule for the network. */ |
||||
@Module |
||||
public class ProtocolScheduleModule { |
||||
|
||||
/** Default constructor. */ |
||||
public ProtocolScheduleModule() {} |
||||
|
||||
/** |
||||
* Provides the protocol schedule builder. |
||||
* |
||||
* @param config the genesis config options |
||||
* @param protocolSpecAdapters the protocol spec adapters |
||||
* @param privacyParameters the privacy parameters |
||||
* @param isRevertReasonEnabled whether revert reason is enabled |
||||
* @param evmConfiguration the EVM configuration |
||||
* @param badBlockManager the bad block manager |
||||
* @param isParallelTxProcessingEnabled whether parallel tx processing is enabled |
||||
* @param metricsSystem the metrics system |
||||
* @param miningParameters the mining parameters |
||||
* @return the protocol schedule builder |
||||
*/ |
||||
@Singleton |
||||
@Provides |
||||
public ProtocolScheduleBuilder provideProtocolScheduleBuilder( |
||||
final GenesisConfigOptions config, |
||||
final ProtocolSpecAdapters protocolSpecAdapters, |
||||
final PrivacyParameters privacyParameters, |
||||
final boolean isRevertReasonEnabled, |
||||
final EvmConfiguration evmConfiguration, |
||||
final BadBlockManager badBlockManager, |
||||
final boolean isParallelTxProcessingEnabled, |
||||
final MetricsSystem metricsSystem, |
||||
final MiningParameters miningParameters) { |
||||
|
||||
ProtocolScheduleBuilder builder = |
||||
new ProtocolScheduleBuilder( |
||||
config, |
||||
config.getChainId(), |
||||
protocolSpecAdapters, |
||||
privacyParameters, |
||||
isRevertReasonEnabled, |
||||
evmConfiguration, |
||||
miningParameters, |
||||
badBlockManager, |
||||
isParallelTxProcessingEnabled, |
||||
metricsSystem); |
||||
|
||||
return builder; |
||||
} |
||||
|
||||
/** |
||||
* Provides the protocol schedule. |
||||
* |
||||
* @param builder the protocol schedule builder |
||||
* @param config the genesis config options |
||||
* @return the protocol schedule |
||||
*/ |
||||
@Provides |
||||
public ProtocolSchedule createProtocolSchedule( |
||||
final ProtocolScheduleBuilder builder, final GenesisConfigOptions config) { |
||||
final Optional<BigInteger> chainId = config.getChainId().or(() -> builder.getDefaultChainId()); |
||||
DefaultProtocolSchedule protocolSchedule = new DefaultProtocolSchedule(chainId); |
||||
builder.initSchedule(protocolSchedule, chainId); |
||||
return protocolSchedule; |
||||
} |
||||
} |
@ -0,0 +1,51 @@ |
||||
/* |
||||
* 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.ethereum.components; |
||||
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSpecs; |
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder; |
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration; |
||||
import org.hyperledger.besu.plugin.services.MetricsSystem; |
||||
|
||||
import javax.inject.Named; |
||||
|
||||
import dagger.Module; |
||||
import dagger.Provides; |
||||
|
||||
/** Provides protocol specs for network forks. */ |
||||
@Module |
||||
public class ProtocolSpecModule { |
||||
|
||||
/** Default constructor. */ |
||||
public ProtocolSpecModule() {} |
||||
|
||||
/** |
||||
* Provides the protocol spec for the frontier network fork. |
||||
* |
||||
* @param evmConfiguration the EVM configuration |
||||
* @param isParalleltxEnabled whether parallel tx processing is enabled |
||||
* @param metricsSystem the metrics system |
||||
* @return the protocol spec for the frontier network fork |
||||
*/ |
||||
@Provides |
||||
@Named("frontier") |
||||
public ProtocolSpecBuilder frontierProtocolSpec( |
||||
final EvmConfiguration evmConfiguration, |
||||
final boolean isParalleltxEnabled, |
||||
final MetricsSystem metricsSystem) { |
||||
return MainnetProtocolSpecs.frontierDefinition( |
||||
evmConfiguration, isParalleltxEnabled, metricsSystem); |
||||
} |
||||
} |
@ -0,0 +1,32 @@ |
||||
/* |
||||
* 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.ethereum.core.components; |
||||
|
||||
import org.hyperledger.besu.ethereum.components.ProtocolScheduleModule; |
||||
import org.hyperledger.besu.ethereum.core.MiningParameters; |
||||
|
||||
import javax.inject.Singleton; |
||||
|
||||
import dagger.Subcomponent; |
||||
|
||||
@Singleton |
||||
@Subcomponent( |
||||
modules = { |
||||
MiningParametersModule.class, |
||||
ProtocolScheduleModule.class, |
||||
}) |
||||
public interface EthereumCoreComponent { |
||||
MiningParameters getMiningParameters(); |
||||
} |
@ -0,0 +1,64 @@ |
||||
/* |
||||
* 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.ethereum.core.components; |
||||
|
||||
import org.hyperledger.besu.datatypes.Address; |
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; |
||||
import org.hyperledger.besu.ethereum.core.MiningParameters; |
||||
|
||||
import javax.inject.Named; |
||||
|
||||
import dagger.Module; |
||||
import dagger.Provides; |
||||
|
||||
@Module |
||||
public class MiningParametersModule { |
||||
|
||||
@Provides |
||||
@Named("defaultMiningParameters") |
||||
protected MiningParameters createImmutableMiningParams() { |
||||
return ImmutableMiningParameters.builder().build(); |
||||
} |
||||
|
||||
@Provides |
||||
@Named("noMining") |
||||
protected MiningParameters createNoMining() { |
||||
return ImmutableMiningParameters.builder() |
||||
.mutableInitValues( |
||||
ImmutableMiningParameters.MutableInitValues.builder().isMiningEnabled(false).build()) |
||||
.build(); |
||||
} |
||||
|
||||
@Provides |
||||
@Named("zeroGas") |
||||
MiningParameters createZeroGasMining(final @Named("emptyCoinbase") Address coinbase) { |
||||
final MiningParameters miningParameters = |
||||
ImmutableMiningParameters.builder() |
||||
.mutableInitValues( |
||||
ImmutableMiningParameters.MutableInitValues.builder() |
||||
.isMiningEnabled(true) |
||||
.minTransactionGasPrice(Wei.ZERO) |
||||
.coinbase(coinbase) |
||||
.build()) |
||||
.build(); |
||||
return miningParameters; |
||||
} |
||||
|
||||
@Provides |
||||
MiningParameters provideMiningParameters() { |
||||
throw new IllegalStateException("unimplemented"); |
||||
} |
||||
} |
@ -1,58 +0,0 @@ |
||||
/* |
||||
* Copyright 2019 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. |
||||
*/ |
||||
|
||||
apply plugin: 'java-library' |
||||
|
||||
jar { |
||||
archiveBaseName = 'besu-retesteth' |
||||
manifest { |
||||
attributes( |
||||
'Specification-Title': archiveBaseName, |
||||
'Specification-Version': project.version, |
||||
'Implementation-Title': archiveBaseName, |
||||
'Implementation-Version': calculateVersion(), |
||||
'Commit-Hash': getGitCommitDetails(40).hash |
||||
) |
||||
} |
||||
} |
||||
|
||||
dependencies { |
||||
api 'org.slf4j:slf4j-api' |
||||
|
||||
implementation project(':config') |
||||
implementation project(':datatypes') |
||||
implementation project(':ethereum:api') |
||||
implementation project(':ethereum:api') |
||||
implementation project(':ethereum:blockcreation') |
||||
implementation project(':ethereum:core') |
||||
implementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') |
||||
implementation project(':ethereum:eth') |
||||
implementation project(':ethereum:p2p') |
||||
implementation project(':ethereum:rlp') |
||||
implementation project(':evm') |
||||
implementation project(':metrics:core') |
||||
implementation project(':nat') |
||||
implementation project(':services:kvstore') |
||||
implementation project(':util') |
||||
|
||||
implementation 'com.google.guava:guava' |
||||
implementation 'io.vertx:vertx-core' |
||||
implementation 'io.vertx:vertx-web' |
||||
implementation 'com.fasterxml.jackson.core:jackson-databind' |
||||
implementation 'io.tmio:tuweni-bytes' |
||||
implementation 'io.tmio:tuweni-units' |
||||
|
||||
testImplementation 'org.assertj:assertj-core' |
||||
testImplementation 'org.junit.jupiter:junit-jupiter' |
||||
testImplementation 'org.mockito:mockito-core' |
||||
} |
@ -1,145 +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.ethereum.retesteth; |
||||
|
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.BlockValidator; |
||||
import org.hyperledger.besu.ethereum.MainnetBlockValidator; |
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager; |
||||
import org.hyperledger.besu.ethereum.core.BlockHeader; |
||||
import org.hyperledger.besu.ethereum.core.BlockImporter; |
||||
import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; |
||||
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; |
||||
import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; |
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockImporter; |
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor; |
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; |
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; |
||||
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; |
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.util.Optional; |
||||
import java.util.function.Predicate; |
||||
|
||||
public class NoRewardProtocolScheduleWrapper implements ProtocolSchedule { |
||||
|
||||
private final ProtocolSchedule delegate; |
||||
private final BadBlockManager badBlockManager; |
||||
|
||||
NoRewardProtocolScheduleWrapper( |
||||
final ProtocolSchedule delegate, final BadBlockManager badBlockManager) { |
||||
this.delegate = delegate; |
||||
this.badBlockManager = badBlockManager; |
||||
} |
||||
|
||||
@Override |
||||
public ProtocolSpec getByBlockHeader(final ProcessableBlockHeader blockHeader) { |
||||
final ProtocolSpec original = delegate.getByBlockHeader(blockHeader); |
||||
final BlockProcessor noRewardBlockProcessor = |
||||
new MainnetBlockProcessor( |
||||
original.getTransactionProcessor(), |
||||
original.getTransactionReceiptFactory(), |
||||
Wei.ZERO, |
||||
original.getMiningBeneficiaryCalculator(), |
||||
original.isSkipZeroBlockRewards(), |
||||
delegate); |
||||
final BlockValidator noRewardBlockValidator = |
||||
new MainnetBlockValidator( |
||||
original.getBlockHeaderValidator(), |
||||
original.getBlockBodyValidator(), |
||||
noRewardBlockProcessor, |
||||
badBlockManager); |
||||
final BlockImporter noRewardBlockImporter = new MainnetBlockImporter(noRewardBlockValidator); |
||||
return new ProtocolSpec( |
||||
original.getName(), |
||||
original.getEvm(), |
||||
original.getTransactionValidatorFactory(), |
||||
original.getTransactionProcessor(), |
||||
original.getPrivateTransactionProcessor(), |
||||
original.getBlockHeaderValidator(), |
||||
original.getOmmerHeaderValidator(), |
||||
original.getBlockBodyValidator(), |
||||
noRewardBlockProcessor, |
||||
noRewardBlockImporter, |
||||
noRewardBlockValidator, |
||||
original.getBlockHeaderFunctions(), |
||||
original.getTransactionReceiptFactory(), |
||||
original.getDifficultyCalculator(), |
||||
Wei.ZERO, // block reward
|
||||
original.getMiningBeneficiaryCalculator(), |
||||
original.getPrecompileContractRegistry(), |
||||
original.isSkipZeroBlockRewards(), |
||||
original.getGasCalculator(), |
||||
original.getGasLimitCalculator(), |
||||
original.getFeeMarket(), |
||||
Optional.empty(), |
||||
original.getWithdrawalsValidator(), |
||||
original.getWithdrawalsProcessor(), |
||||
original.getRequestsValidator(), |
||||
original.getRequestProcessorCoordinator(), |
||||
original.getBlockHashProcessor(), |
||||
original.isPoS(), |
||||
original.isReplayProtectionSupported()); |
||||
} |
||||
|
||||
@Override |
||||
public boolean anyMatch(final Predicate<ScheduledProtocolSpec> predicate) { |
||||
return delegate.anyMatch(predicate); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isOnMilestoneBoundary(final BlockHeader blockHeader) { |
||||
return delegate.isOnMilestoneBoundary(blockHeader); |
||||
} |
||||
|
||||
@Override |
||||
public Optional<BigInteger> getChainId() { |
||||
return delegate.getChainId(); |
||||
} |
||||
|
||||
@Override |
||||
public void putBlockNumberMilestone(final long blockNumber, final ProtocolSpec protocolSpec) { |
||||
delegate.putBlockNumberMilestone(blockNumber, protocolSpec); |
||||
} |
||||
|
||||
@Override |
||||
public void putTimestampMilestone(final long timestamp, final ProtocolSpec protocolSpec) { |
||||
delegate.putTimestampMilestone(timestamp, protocolSpec); |
||||
} |
||||
|
||||
@Override |
||||
public Optional<ScheduledProtocolSpec.Hardfork> hardforkFor( |
||||
final Predicate<ScheduledProtocolSpec> predicate) { |
||||
return delegate.hardforkFor(predicate); |
||||
} |
||||
|
||||
@Override |
||||
public String listMilestones() { |
||||
return delegate.listMilestones(); |
||||
} |
||||
|
||||
@Override |
||||
public void setPermissionTransactionFilter( |
||||
final PermissionTransactionFilter permissionTransactionFilter) { |
||||
delegate.setPermissionTransactionFilter(permissionTransactionFilter); |
||||
} |
||||
|
||||
@Override |
||||
public void setPublicWorldStateArchiveForPrivacyBlockProcessor( |
||||
final WorldStateArchive publicWorldStateArchive) { |
||||
delegate.setPublicWorldStateArchiveForPrivacyBlockProcessor(publicWorldStateArchive); |
||||
} |
||||
} |
@ -1,60 +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.ethereum.retesteth; |
||||
|
||||
import java.time.Clock; |
||||
import java.time.Instant; |
||||
import java.time.ZoneId; |
||||
import java.util.Optional; |
||||
|
||||
public class RetestethClock extends Clock { |
||||
|
||||
private Optional<Instant> fixedInstant; |
||||
private final Clock delegateClock; |
||||
|
||||
RetestethClock() { |
||||
this(Clock.systemUTC()); |
||||
} |
||||
|
||||
private RetestethClock(final Clock delegateClock) { |
||||
fixedInstant = Optional.empty(); |
||||
this.delegateClock = delegateClock; |
||||
} |
||||
|
||||
@Override |
||||
public ZoneId getZone() { |
||||
return delegateClock.getZone(); |
||||
} |
||||
|
||||
@Override |
||||
public Clock withZone(final ZoneId zone) { |
||||
final RetestethClock zonedClock = new RetestethClock(delegateClock.withZone(zone)); |
||||
zonedClock.fixedInstant = fixedInstant; |
||||
return zonedClock; |
||||
} |
||||
|
||||
@Override |
||||
public Instant instant() { |
||||
return fixedInstant.orElseGet(delegateClock::instant); |
||||
} |
||||
|
||||
public void resetTime(final long time) { |
||||
fixedInstant = Optional.of(Instant.ofEpochSecond(time)); |
||||
} |
||||
|
||||
public void advanceSeconds(final long seconds) { |
||||
fixedInstant = Optional.of(Instant.ofEpochSecond(instant().getEpochSecond() + seconds)); |
||||
} |
||||
} |
@ -1,370 +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.ethereum.retesteth; |
||||
|
||||
import static org.hyperledger.besu.config.JsonUtil.normalizeKeys; |
||||
|
||||
import org.hyperledger.besu.config.JsonGenesisConfigOptions; |
||||
import org.hyperledger.besu.config.JsonUtil; |
||||
import org.hyperledger.besu.datatypes.Address; |
||||
import org.hyperledger.besu.datatypes.Hash; |
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.ProtocolContext; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockReplay; |
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; |
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager; |
||||
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain; |
||||
import org.hyperledger.besu.ethereum.chain.GenesisState; |
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain; |
||||
import org.hyperledger.besu.ethereum.chain.VariablesStorage; |
||||
import org.hyperledger.besu.ethereum.core.Block; |
||||
import org.hyperledger.besu.ethereum.core.BlockHeader; |
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; |
||||
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; |
||||
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitValues; |
||||
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.Unstable; |
||||
import org.hyperledger.besu.ethereum.core.MiningParameters; |
||||
import org.hyperledger.besu.ethereum.core.MutableWorldState; |
||||
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; |
||||
import org.hyperledger.besu.ethereum.eth.manager.EthContext; |
||||
import org.hyperledger.besu.ethereum.eth.manager.EthMessages; |
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeers; |
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; |
||||
import org.hyperledger.besu.ethereum.eth.sync.SyncMode; |
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolFactory; |
||||
import org.hyperledger.besu.ethereum.forkid.ForkIdManager; |
||||
import org.hyperledger.besu.ethereum.mainnet.EpochCalculator; |
||||
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; |
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; |
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; |
||||
import org.hyperledger.besu.ethereum.mainnet.PoWHasher; |
||||
import org.hyperledger.besu.ethereum.mainnet.PoWSolution; |
||||
import org.hyperledger.besu.ethereum.mainnet.PoWSolver; |
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; |
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; |
||||
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; |
||||
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage; |
||||
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage; |
||||
import org.hyperledger.besu.ethereum.storage.keyvalue.WorldStatePreimageKeyValueStorage; |
||||
import org.hyperledger.besu.ethereum.trie.forest.ForestWorldStateArchive; |
||||
import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; |
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; |
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; |
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration; |
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; |
||||
import org.hyperledger.besu.plugin.services.MetricsSystem; |
||||
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; |
||||
import org.hyperledger.besu.util.Subscribers; |
||||
import org.hyperledger.besu.util.number.Fraction; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
import java.util.concurrent.locks.ReentrantLock; |
||||
import java.util.function.Supplier; |
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
import com.fasterxml.jackson.databind.node.ObjectNode; |
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.apache.tuweni.bytes.Bytes32; |
||||
import org.apache.tuweni.units.bigints.UInt256; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
public class RetestethContext { |
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RetestethContext.class); |
||||
private static final PoWHasher NO_WORK_HASHER = |
||||
(final long nonce, final long number, EpochCalculator epochCalc, final Bytes headerHash) -> |
||||
new PoWSolution(nonce, Hash.ZERO, UInt256.ZERO, Hash.ZERO); |
||||
public static final int MAX_PEERS = 25; |
||||
|
||||
private final ReentrantLock contextLock = new ReentrantLock(); |
||||
private final BadBlockManager badBlockManager = new BadBlockManager(); |
||||
private Address coinbase; |
||||
private Bytes extraData; |
||||
private MutableBlockchain blockchain; |
||||
private ProtocolContext protocolContext; |
||||
private BlockchainQueries blockchainQueries; |
||||
private ProtocolSchedule protocolSchedule; |
||||
private BlockHeaderFunctions blockHeaderFunctions; |
||||
private HeaderValidationMode headerValidationMode; |
||||
private BlockReplay blockReplay; |
||||
private RetestethClock retestethClock; |
||||
private MiningParameters miningParameters; |
||||
private TransactionPool transactionPool; |
||||
private EthScheduler ethScheduler; |
||||
private PoWSolver poWSolver; |
||||
|
||||
private Optional<Bytes> terminalTotalDifficulty; |
||||
private Optional<Bytes32> mixHash; |
||||
|
||||
public boolean resetContext( |
||||
final String genesisConfigString, final String sealEngine, final Optional<Long> clockTime) { |
||||
contextLock.lock(); |
||||
try { |
||||
tearDownContext(); |
||||
return buildContext(genesisConfigString, sealEngine, clockTime); |
||||
} catch (final Exception e) { |
||||
LOG.error("Error shutting down existing runner", e); |
||||
return false; |
||||
} finally { |
||||
contextLock.unlock(); |
||||
} |
||||
} |
||||
|
||||
private void tearDownContext() { |
||||
try { |
||||
if (ethScheduler != null) { |
||||
ethScheduler.stop(); |
||||
ethScheduler.awaitStop(); |
||||
} |
||||
} catch (final InterruptedException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
private boolean buildContext( |
||||
final String genesisConfigString, final String sealEngine, final Optional<Long> clockTime) { |
||||
final ObjectNode genesisConfig = |
||||
normalizeKeys(JsonUtil.objectNodeFromString(genesisConfigString)); |
||||
|
||||
retestethClock = new RetestethClock(); |
||||
clockTime.ifPresent(retestethClock::resetTime); |
||||
final MetricsSystem metricsSystem = new NoOpMetricsSystem(); |
||||
|
||||
terminalTotalDifficulty = |
||||
Optional.ofNullable(genesisConfig.get("params")) |
||||
.map(n -> n.get("terminaltotaldifficulty")) |
||||
.map(JsonNode::asText) |
||||
.map(Bytes::fromHexString); |
||||
|
||||
final JsonGenesisConfigOptions jsonGenesisConfigOptions = |
||||
JsonGenesisConfigOptions.fromJsonObject( |
||||
JsonUtil.getObjectNode(genesisConfig, "config").get()); |
||||
protocolSchedule = |
||||
MainnetProtocolSchedule.fromConfig( |
||||
jsonGenesisConfigOptions, |
||||
EvmConfiguration.DEFAULT, |
||||
miningParameters, |
||||
badBlockManager, |
||||
false, |
||||
new NoOpMetricsSystem()); |
||||
if ("NoReward".equalsIgnoreCase(sealEngine)) { |
||||
protocolSchedule = new NoRewardProtocolScheduleWrapper(protocolSchedule, badBlockManager); |
||||
} |
||||
blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); |
||||
|
||||
final GenesisState genesisState = GenesisState.fromJson(genesisConfigString, protocolSchedule); |
||||
coinbase = genesisState.getBlock().getHeader().getCoinbase(); |
||||
extraData = genesisState.getBlock().getHeader().getExtraData(); |
||||
mixHash = Optional.ofNullable(genesisState.getBlock().getHeader().getMixHashOrPrevRandao()); |
||||
|
||||
final WorldStateArchive worldStateArchive = |
||||
new ForestWorldStateArchive( |
||||
new WorldStateStorageCoordinator( |
||||
new ForestWorldStateKeyValueStorage(new InMemoryKeyValueStorage())), |
||||
new WorldStatePreimageKeyValueStorage(new InMemoryKeyValueStorage()), |
||||
EvmConfiguration.DEFAULT); |
||||
final MutableWorldState worldState = worldStateArchive.getMutable(); |
||||
genesisState.writeStateTo(worldState); |
||||
|
||||
blockchain = createInMemoryBlockchain(genesisState.getBlock()); |
||||
protocolContext = new ProtocolContext(blockchain, worldStateArchive, null, badBlockManager); |
||||
|
||||
blockchainQueries = |
||||
new BlockchainQueries( |
||||
protocolSchedule, blockchain, worldStateArchive, ethScheduler, miningParameters); |
||||
|
||||
final String sealengine = JsonUtil.getString(genesisConfig, "sealengine", ""); |
||||
headerValidationMode = |
||||
"NoProof".equals(sealengine) || "NoReward".equals(sealEngine) |
||||
? HeaderValidationMode.LIGHT |
||||
: HeaderValidationMode.FULL; |
||||
|
||||
miningParameters = |
||||
ImmutableMiningParameters.builder() |
||||
.mutableInitValues( |
||||
MutableInitValues.builder() |
||||
.coinbase(coinbase) |
||||
.extraData(extraData) |
||||
.targetGasLimit(blockchain.getChainHeadHeader().getGasLimit()) |
||||
.minBlockOccupancyRatio(0.0) |
||||
.minTransactionGasPrice(Wei.ZERO) |
||||
.build()) |
||||
.unstable(Unstable.builder().powJobTimeToLive(1000).maxOmmerDepth(8).build()) |
||||
.build(); |
||||
miningParameters.setMinTransactionGasPrice(Wei.ZERO); |
||||
poWSolver = |
||||
("NoProof".equals(sealengine) || "NoReward".equals(sealEngine)) |
||||
? new PoWSolver( |
||||
miningParameters, |
||||
NO_WORK_HASHER, |
||||
false, |
||||
Subscribers.none(), |
||||
new EpochCalculator.DefaultEpochCalculator()) |
||||
: new PoWSolver( |
||||
miningParameters, |
||||
PoWHasher.ETHASH_LIGHT, |
||||
false, |
||||
Subscribers.none(), |
||||
new EpochCalculator.DefaultEpochCalculator()); |
||||
|
||||
blockReplay = |
||||
new BlockReplay(protocolSchedule, protocolContext, blockchainQueries.getBlockchain()); |
||||
|
||||
final Bytes localNodeKey = Bytes.wrap(new byte[64]); |
||||
|
||||
// mining support
|
||||
|
||||
final Supplier<ProtocolSpec> currentProtocolSpecSupplier = |
||||
() -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()); |
||||
final EthPeers ethPeers = |
||||
new EthPeers( |
||||
"reteseth", |
||||
currentProtocolSpecSupplier, |
||||
retestethClock, |
||||
metricsSystem, |
||||
EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE, |
||||
Collections.emptyList(), |
||||
localNodeKey, |
||||
MAX_PEERS, |
||||
MAX_PEERS, |
||||
false, |
||||
SyncMode.FAST, |
||||
new ForkIdManager(blockchain, List.of(), List.of(), false)); |
||||
final SyncState syncState = new SyncState(blockchain, ethPeers); |
||||
|
||||
ethScheduler = new EthScheduler(1, 1, 1, 1, metricsSystem); |
||||
final EthContext ethContext = new EthContext(ethPeers, new EthMessages(), ethScheduler); |
||||
|
||||
final TransactionPoolConfiguration transactionPoolConfiguration = |
||||
ImmutableTransactionPoolConfiguration.builder() |
||||
.txPoolLimitByAccountPercentage(Fraction.fromFloat(0.004f)) |
||||
.build(); |
||||
|
||||
transactionPool = |
||||
TransactionPoolFactory.createTransactionPool( |
||||
protocolSchedule, |
||||
protocolContext, |
||||
ethContext, |
||||
retestethClock, |
||||
metricsSystem, |
||||
syncState, |
||||
transactionPoolConfiguration, |
||||
new BlobCache(), |
||||
MiningParameters.newDefault()); |
||||
|
||||
if (LOG.isTraceEnabled()) { |
||||
LOG.trace("Genesis Block {} ", genesisState.getBlock()); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static MutableBlockchain createInMemoryBlockchain(final Block genesisBlock) { |
||||
return createInMemoryBlockchain(genesisBlock, new MainnetBlockHeaderFunctions()); |
||||
} |
||||
|
||||
private static MutableBlockchain createInMemoryBlockchain( |
||||
final Block genesisBlock, final BlockHeaderFunctions blockHeaderFunctions) { |
||||
final InMemoryKeyValueStorage keyValueStorage = new InMemoryKeyValueStorage(); |
||||
final VariablesStorage variablesStorage = |
||||
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()); |
||||
return DefaultBlockchain.createMutable( |
||||
genesisBlock, |
||||
new KeyValueStoragePrefixedKeyBlockchainStorage( |
||||
keyValueStorage, variablesStorage, blockHeaderFunctions, false), |
||||
new NoOpMetricsSystem(), |
||||
100); |
||||
} |
||||
|
||||
public ProtocolSchedule getProtocolSchedule() { |
||||
return protocolSchedule; |
||||
} |
||||
|
||||
public BlockHeaderFunctions getBlockHeaderFunctions() { |
||||
return blockHeaderFunctions; |
||||
} |
||||
|
||||
public ProtocolContext getProtocolContext() { |
||||
return protocolContext; |
||||
} |
||||
|
||||
public EthScheduler getEthScheduler() { |
||||
return ethScheduler; |
||||
} |
||||
|
||||
public void setEthScheduler(final EthScheduler ethScheduler) { |
||||
this.ethScheduler = ethScheduler; |
||||
} |
||||
|
||||
public long getBlockHeight() { |
||||
return blockchain.getChainHeadBlockNumber(); |
||||
} |
||||
|
||||
public ProtocolSpec getProtocolSpec(final BlockHeader blockHeader) { |
||||
return getProtocolSchedule().getByBlockHeader(blockHeader); |
||||
} |
||||
|
||||
public BlockHeader getBlockHeader(final long blockNumber) { |
||||
return blockchain.getBlockHeader(blockNumber).get(); |
||||
} |
||||
|
||||
public BlockchainQueries getBlockchainQueries() { |
||||
return blockchainQueries; |
||||
} |
||||
|
||||
public HeaderValidationMode getHeaderValidationMode() { |
||||
return headerValidationMode; |
||||
} |
||||
|
||||
BlockReplay getBlockReplay() { |
||||
return blockReplay; |
||||
} |
||||
|
||||
public TransactionPool getTransactionPool() { |
||||
return transactionPool; |
||||
} |
||||
|
||||
public MiningParameters getMiningParameters() { |
||||
return miningParameters; |
||||
} |
||||
|
||||
public MutableBlockchain getBlockchain() { |
||||
return blockchain; |
||||
} |
||||
|
||||
public RetestethClock getRetestethClock() { |
||||
return retestethClock; |
||||
} |
||||
|
||||
public Optional<Bytes> getTerminalTotalDifficulty() { |
||||
return terminalTotalDifficulty; |
||||
} |
||||
|
||||
public Optional<Bytes32> getMixHash() { |
||||
return mixHash; |
||||
} |
||||
|
||||
public PoWSolver getEthHashSolver() { |
||||
return poWSolver; |
||||
} |
||||
} |
@ -1,122 +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.ethereum.retesteth; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcHttpService; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.health.LivenessCheck; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.DebugAccountRange; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.DebugStorageRangeAt; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthBlockNumber; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBalance; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBlockByHash; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBlockByNumber; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetCode; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetTransactionCount; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthSendRawTransaction; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Web3ClientVersion; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; |
||||
import org.hyperledger.besu.ethereum.core.DummySynchronizer; |
||||
import org.hyperledger.besu.ethereum.core.Synchronizer; |
||||
import org.hyperledger.besu.ethereum.retesteth.methods.TestGetLogHash; |
||||
import org.hyperledger.besu.ethereum.retesteth.methods.TestImportRawBlock; |
||||
import org.hyperledger.besu.ethereum.retesteth.methods.TestMineBlocks; |
||||
import org.hyperledger.besu.ethereum.retesteth.methods.TestModifyTimestamp; |
||||
import org.hyperledger.besu.ethereum.retesteth.methods.TestRewindToBlock; |
||||
import org.hyperledger.besu.ethereum.retesteth.methods.TestSetChainParams; |
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; |
||||
import org.hyperledger.besu.nat.NatService; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.Map; |
||||
import java.util.Optional; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import io.vertx.core.Vertx; |
||||
|
||||
public class RetestethService { |
||||
|
||||
private final JsonRpcHttpService jsonRpcHttpService; |
||||
private final Vertx vertx; |
||||
|
||||
private final RetestethContext retestethContext; |
||||
|
||||
public RetestethService( |
||||
final String clientVersion, |
||||
final RetestethConfiguration retestethConfiguration, |
||||
final JsonRpcConfiguration jsonRpcConfiguration) { |
||||
vertx = Vertx.vertx(); |
||||
retestethContext = new RetestethContext(); |
||||
|
||||
final BlockResultFactory blockResult = new BlockResultFactory(); |
||||
final NatService natService = new NatService(Optional.empty()); |
||||
|
||||
// Synchronizer needed by RPC methods. Didn't wanna mock it, since this isn't the test module.
|
||||
Synchronizer sync = new DummySynchronizer(); |
||||
|
||||
final Map<String, JsonRpcMethod> jsonRpcMethods = |
||||
mapOf( |
||||
new Web3ClientVersion(clientVersion), |
||||
new TestSetChainParams(retestethContext), |
||||
new TestImportRawBlock(retestethContext), |
||||
new EthBlockNumber(retestethContext::getBlockchainQueries, true), |
||||
new EthGetBlockByNumber( |
||||
retestethContext::getBlockchainQueries, blockResult, sync, true), |
||||
new DebugAccountRange(retestethContext::getBlockchainQueries), |
||||
new EthGetBalance(retestethContext::getBlockchainQueries), |
||||
new EthGetBlockByHash(retestethContext::getBlockchainQueries, blockResult, true), |
||||
new EthGetCode(retestethContext::getBlockchainQueries), |
||||
new EthGetTransactionCount( |
||||
retestethContext::getBlockchainQueries, retestethContext::getTransactionPool), |
||||
new DebugStorageRangeAt( |
||||
retestethContext::getBlockchainQueries, retestethContext::getBlockReplay, true), |
||||
new TestModifyTimestamp(retestethContext), |
||||
new EthSendRawTransaction(retestethContext::getTransactionPool, true), |
||||
new TestMineBlocks(retestethContext), |
||||
new TestGetLogHash(retestethContext), |
||||
new TestRewindToBlock(retestethContext)); |
||||
|
||||
jsonRpcHttpService = |
||||
new JsonRpcHttpService( |
||||
vertx, |
||||
retestethConfiguration.getDataPath(), |
||||
jsonRpcConfiguration, |
||||
new NoOpMetricsSystem(), |
||||
natService, |
||||
jsonRpcMethods, |
||||
new HealthService(new LivenessCheck()), |
||||
HealthService.ALWAYS_HEALTHY); |
||||
} |
||||
|
||||
public void start() { |
||||
jsonRpcHttpService.start(); |
||||
} |
||||
|
||||
public void close() { |
||||
stop(); |
||||
} |
||||
|
||||
public void stop() { |
||||
jsonRpcHttpService.stop(); |
||||
vertx.close(); |
||||
} |
||||
|
||||
private static Map<String, JsonRpcMethod> mapOf(final JsonRpcMethod... rpcMethods) { |
||||
return Arrays.stream(rpcMethods) |
||||
.collect(Collectors.toMap(JsonRpcMethod::getName, rpcMethod -> rpcMethod)); |
||||
} |
||||
} |
@ -1,73 +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.ethereum.retesteth.methods; |
||||
|
||||
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.parameters.JsonRpcParameter.JsonRpcParameterException; |
||||
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; |
||||
import org.hyperledger.besu.evm.log.Log; |
||||
|
||||
import java.util.Optional; |
||||
|
||||
public class TestGetLogHash implements JsonRpcMethod { |
||||
private final RetestethContext context; |
||||
|
||||
public TestGetLogHash(final RetestethContext context) { |
||||
this.context = context; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return "test_getLogHash"; |
||||
} |
||||
|
||||
@Override |
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { |
||||
final Hash txHash; |
||||
try { |
||||
txHash = requestContext.getRequiredParameter(0, Hash.class); |
||||
} catch (JsonRpcParameterException e) { |
||||
throw new InvalidJsonRpcParameters( |
||||
"Invalid transaction hash parameter (index 0)", |
||||
RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, |
||||
e); |
||||
} |
||||
|
||||
final Optional<TransactionReceiptWithMetadata> receipt = |
||||
context |
||||
.getBlockchainQueries() |
||||
.transactionReceiptByTransactionHash(txHash, context.getProtocolSchedule()); |
||||
return new JsonRpcSuccessResponse( |
||||
requestContext.getRequest().getId(), |
||||
receipt.map(this::calculateLogHash).orElse(Hash.EMPTY_LIST_HASH).toString()); |
||||
} |
||||
|
||||
private Hash calculateLogHash( |
||||
final TransactionReceiptWithMetadata transactionReceiptWithMetadata) { |
||||
return Hash.hash( |
||||
RLP.encode( |
||||
out -> |
||||
out.writeList( |
||||
transactionReceiptWithMetadata.getReceipt().getLogsList(), Log::writeTo))); |
||||
} |
||||
} |
@ -1,107 +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.ethereum.retesteth.methods; |
||||
|
||||
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.JsonRpcMethod; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; |
||||
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.core.Block; |
||||
import org.hyperledger.besu.ethereum.core.BlockImporter; |
||||
import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; |
||||
import org.hyperledger.besu.ethereum.retesteth.RetestethContext; |
||||
import org.hyperledger.besu.ethereum.rlp.RLP; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPException; |
||||
|
||||
import java.util.Collections; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
public class TestImportRawBlock implements JsonRpcMethod { |
||||
private static final Logger LOG = LoggerFactory.getLogger(TestImportRawBlock.class); |
||||
|
||||
public static final String METHOD_NAME = "test_importRawBlock"; |
||||
|
||||
private final RetestethContext context; |
||||
|
||||
public TestImportRawBlock(final RetestethContext context) { |
||||
this.context = context; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return METHOD_NAME; |
||||
} |
||||
|
||||
@Override |
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { |
||||
final String input; |
||||
try { |
||||
input = requestContext.getRequiredParameter(0, String.class); |
||||
} catch (JsonRpcParameterException e) { |
||||
throw new InvalidJsonRpcParameters( |
||||
"Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); |
||||
} |
||||
final ProtocolContext protocolContext = this.context.getProtocolContext(); |
||||
|
||||
final Block block; |
||||
try { |
||||
block = |
||||
Block.readFrom(RLP.input(Bytes.fromHexString(input)), context.getBlockHeaderFunctions()); |
||||
} catch (final RLPException | IllegalArgumentException e) { |
||||
LOG.debug("Failed to parse block RLP", e); |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), RpcErrorType.BLOCK_RLP_IMPORT_ERROR); |
||||
} |
||||
|
||||
// retesteth expects test_rawImportBlock to not only import the block, but append it to head
|
||||
if (context.getBlockchain().contains(block.getHash())) { |
||||
// if we already have the block but it is not head, append it:
|
||||
context |
||||
.getBlockchain() |
||||
.appendBlock( |
||||
block, |
||||
context |
||||
.getBlockchain() |
||||
.getTxReceipts(block.getHash()) |
||||
.orElse(Collections.emptyList())); |
||||
} else { |
||||
// otherwise attempt to import the block
|
||||
final BlockImporter blockImporter = |
||||
context.getProtocolSpec(block.getHeader()).getBlockImporter(); |
||||
final BlockImportResult result = |
||||
blockImporter.importBlock( |
||||
protocolContext, |
||||
block, |
||||
context.getHeaderValidationMode(), |
||||
context.getHeaderValidationMode()); |
||||
if (!result.isImported()) { |
||||
LOG.debug("Failed to import block."); |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), RpcErrorType.BLOCK_IMPORT_ERROR); |
||||
} |
||||
} |
||||
// return success on append or import
|
||||
return new JsonRpcSuccessResponse( |
||||
requestContext.getRequest().getId(), block.getHash().toString()); |
||||
} |
||||
} |
@ -1,97 +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.ethereum.retesteth.methods; |
||||
|
||||
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.JsonRpcMethod; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; |
||||
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.blockcreation.PoWBlockCreator; |
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain; |
||||
import org.hyperledger.besu.ethereum.core.Block; |
||||
import org.hyperledger.besu.ethereum.core.BlockImporter; |
||||
import org.hyperledger.besu.ethereum.core.MiningParameters; |
||||
import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; |
||||
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; |
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; |
||||
import org.hyperledger.besu.ethereum.retesteth.RetestethClock; |
||||
import org.hyperledger.besu.ethereum.retesteth.RetestethContext; |
||||
|
||||
public class TestMineBlocks implements JsonRpcMethod { |
||||
private final RetestethContext context; |
||||
|
||||
public TestMineBlocks(final RetestethContext context) { |
||||
this.context = context; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return "test_mineBlocks"; |
||||
} |
||||
|
||||
@Override |
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { |
||||
long blocksToMine = 0; |
||||
try { |
||||
blocksToMine = requestContext.getRequiredParameter(0, Long.class); |
||||
} catch (JsonRpcParameterException e) { |
||||
throw new InvalidJsonRpcParameters( |
||||
"Invalid blocks to mine (index 0)", RpcErrorType.INVALID_BLOCK_COUNT_PARAMS, e); |
||||
} |
||||
while (blocksToMine-- > 0) { |
||||
if (!mineNewBlock()) { |
||||
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), false); |
||||
} |
||||
} |
||||
|
||||
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true); |
||||
} |
||||
|
||||
private boolean mineNewBlock() { |
||||
final RetestethClock retesethClock = context.getRetestethClock(); |
||||
final ProtocolSchedule protocolSchedule = context.getProtocolSchedule(); |
||||
final ProtocolContext protocolContext = context.getProtocolContext(); |
||||
final MutableBlockchain blockchain = context.getBlockchain(); |
||||
final HeaderValidationMode headerValidationMode = context.getHeaderValidationMode(); |
||||
final MiningParameters miningParameters = context.getMiningParameters(); |
||||
final PoWBlockCreator blockCreator = |
||||
new PoWBlockCreator( |
||||
miningParameters, |
||||
header -> miningParameters.getExtraData(), |
||||
context.getTransactionPool(), |
||||
protocolContext, |
||||
protocolSchedule, |
||||
context.getEthHashSolver(), |
||||
context.getEthScheduler()); |
||||
final Block block = |
||||
blockCreator |
||||
.createBlock(retesethClock.instant().getEpochSecond(), blockchain.getChainHeadHeader()) |
||||
.getBlock(); |
||||
|
||||
// advance clock so next mine won't hit the same timestamp
|
||||
retesethClock.advanceSeconds(1); |
||||
|
||||
final BlockImporter blockImporter = |
||||
protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()).getBlockImporter(); |
||||
final BlockImportResult result = |
||||
blockImporter.importBlock( |
||||
protocolContext, block, headerValidationMode, headerValidationMode); |
||||
return result.isImported(); |
||||
} |
||||
} |
@ -1,51 +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.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.parameters.JsonRpcParameter.JsonRpcParameterException; |
||||
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 { |
||||
|
||||
private final RetestethContext context; |
||||
|
||||
public TestModifyTimestamp(final RetestethContext context) { |
||||
this.context = context; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return "test_modifyTimestamp"; |
||||
} |
||||
|
||||
@Override |
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { |
||||
final long epochSeconds; |
||||
try { |
||||
epochSeconds = requestContext.getRequiredParameter(0, Long.class); |
||||
} catch (JsonRpcParameterException e) { |
||||
throw new InvalidJsonRpcParameters( |
||||
"Invalid timestamp parameter (index 0)", RpcErrorType.INVALID_TIMESTAMP_PARAMS, e); |
||||
} |
||||
context.getRetestethClock().resetTime(epochSeconds); |
||||
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true); |
||||
} |
||||
} |
@ -1,53 +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.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.parameters.JsonRpcParameter.JsonRpcParameterException; |
||||
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 TestRewindToBlock implements JsonRpcMethod { |
||||
private final RetestethContext context; |
||||
|
||||
public static final String METHOD_NAME = "test_rewindToBlock"; |
||||
|
||||
public TestRewindToBlock(final RetestethContext context) { |
||||
this.context = context; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return METHOD_NAME; |
||||
} |
||||
|
||||
@Override |
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { |
||||
final long blockNumber; |
||||
try { |
||||
blockNumber = requestContext.getRequiredParameter(0, Long.TYPE); |
||||
} catch (JsonRpcParameterException e) { |
||||
throw new InvalidJsonRpcParameters( |
||||
"Invalid block number parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); |
||||
} |
||||
|
||||
return new JsonRpcSuccessResponse( |
||||
requestContext.getRequest().getId(), context.getBlockchain().rewindToBlock(blockNumber)); |
||||
} |
||||
} |
@ -1,159 +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.ethereum.retesteth.methods; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; |
||||
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; |
||||
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; |
||||
|
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
import java.util.Optional; |
||||
|
||||
import io.vertx.core.json.JsonObject; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
public class TestSetChainParams implements JsonRpcMethod { |
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestSetChainParams.class); |
||||
|
||||
public static final String METHOD_NAME = "test_setChainParams"; |
||||
private final RetestethContext context; |
||||
|
||||
public TestSetChainParams(final RetestethContext context) { |
||||
this.context = context; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return METHOD_NAME; |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
@Override |
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { |
||||
|
||||
try { |
||||
final JsonObject chainParamsAsJson = |
||||
new JsonObject((Map<String, Object>) requestContext.getRequest().getParams()[0]); |
||||
final String chainParamsAsString = chainParamsAsJson.encodePrettily(); |
||||
LOG.trace("ChainParams {}", chainParamsAsString); |
||||
final String genesisFileAsString = modifyGenesisFile(chainParamsAsString); |
||||
LOG.trace("Genesis {}", genesisFileAsString); |
||||
final boolean result = |
||||
context.resetContext( |
||||
genesisFileAsString, |
||||
chainParamsAsJson.getString("sealEngine", "NoProof"), |
||||
Optional.empty()); |
||||
|
||||
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), result); |
||||
} catch (final Exception e) { |
||||
LOG.error("Unhandled error", e); |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); |
||||
} |
||||
} |
||||
|
||||
private static void maybeMove( |
||||
final JsonObject src, final String srcName, final JsonObject dest, final String destName) { |
||||
if (src.containsKey(srcName)) { |
||||
dest.put(destName, src.getValue(srcName)); |
||||
src.remove(srcName); |
||||
} |
||||
} |
||||
|
||||
private static void maybeMoveToNumber( |
||||
final JsonObject src, final String srcName, final JsonObject dest, final String destName) { |
||||
if (src.containsKey(srcName)) { |
||||
dest.put(destName, Long.decode(src.getString(srcName))); |
||||
src.remove(srcName); |
||||
} |
||||
} |
||||
|
||||
private static void maybeMoveToNumber( |
||||
final JsonObject src, |
||||
final String srcName, |
||||
final JsonObject dest, |
||||
final String destName, |
||||
final long defaultValue) { |
||||
if (src.containsKey(srcName)) { |
||||
dest.put(destName, Long.decode(src.getString(srcName))); |
||||
src.remove(srcName); |
||||
} else { |
||||
dest.put(destName, defaultValue); |
||||
} |
||||
} |
||||
|
||||
private static String modifyGenesisFile(final String initialGenesis) { |
||||
final JsonObject chainParamsJson = new JsonObject(initialGenesis); |
||||
final JsonObject config = new JsonObject(); |
||||
chainParamsJson.put("config", config); |
||||
final JsonObject params = chainParamsJson.getJsonObject("params"); |
||||
final JsonObject genesis = chainParamsJson.getJsonObject("genesis"); |
||||
|
||||
// Whether sealEngine is NoProof, Ethash, or NoReward the genesis file is the same
|
||||
final JsonObject ethash = new JsonObject(); |
||||
config.put("ethash", ethash); |
||||
|
||||
maybeMoveToNumber(params, "homesteadForkBlock", config, "homesteadBlock"); |
||||
maybeMoveToNumber(params, "daoHardforkBlock", config, "daoForkBlock"); |
||||
maybeMoveToNumber(params, "EIP150ForkBlock", config, "eip150Block"); |
||||
maybeMoveToNumber(params, "EIP158ForkBlock", config, "eip158Block"); |
||||
maybeMoveToNumber(params, "byzantiumForkBlock", config, "byzantiumBlock"); |
||||
maybeMoveToNumber(params, "constantinopleForkBlock", config, "constantinopleBlock"); |
||||
maybeMoveToNumber(params, "constantinopleFixForkBlock", config, "petersburgBlock"); |
||||
maybeMoveToNumber(params, "istanbulForkBlock", config, "istanbulBlock"); |
||||
maybeMoveToNumber(params, "muirGlacierForkBlock", config, "muirGlacierBlock"); |
||||
maybeMoveToNumber(params, "berlinForkBlock", config, "berlinBlock"); |
||||
maybeMoveToNumber(params, "londonForkBlock", config, "londonBlock"); |
||||
maybeMoveToNumber(params, "arrowGlacierForkBlock", config, "arrowGlacierBlock"); |
||||
maybeMoveToNumber(params, "grayGlacierForkBlock", config, "grayGlacierBlock"); |
||||
maybeMoveToNumber(params, "mergeNetSplitForkBlock", config, "mergeNetSplitBlock"); |
||||
maybeMoveToNumber(params, "shanghaiForkTime", config, "shanghaiTime"); |
||||
maybeMoveToNumber(params, "cancunForkTime", config, "cancunTime"); |
||||
maybeMoveToNumber(params, "pragueForkTime", config, "pragueTime"); |
||||
maybeMoveToNumber(params, "futureEipsForkTime", config, "futureEipsTime"); |
||||
maybeMoveToNumber(params, "experimentalEipsForkTime", config, "experimentalEipsTime"); |
||||
maybeMoveToNumber(params, "chainID", config, "chainId", 1); |
||||
|
||||
maybeMove(genesis, "author", chainParamsJson, "coinbase"); |
||||
maybeMove(genesis, "difficulty", chainParamsJson, "difficulty"); |
||||
maybeMove(genesis, "extraData", chainParamsJson, "extraData"); |
||||
maybeMove(genesis, "gasLimit", chainParamsJson, "gasLimit"); |
||||
maybeMove(genesis, "mixHash", chainParamsJson, "mixHash"); |
||||
maybeMove(genesis, "nonce", chainParamsJson, "nonce"); |
||||
maybeMove(genesis, "timestamp", chainParamsJson, "timestamp"); |
||||
maybeMove(chainParamsJson, "accounts", chainParamsJson, "alloc"); |
||||
maybeMove(genesis, "baseFeePerGas", chainParamsJson, "baseFeePerGas"); |
||||
|
||||
// strip out precompiles with zero balance
|
||||
final JsonObject alloc = chainParamsJson.getJsonObject("alloc"); |
||||
final Iterator<String> fieldNamesIter = alloc.fieldNames().iterator(); |
||||
while (fieldNamesIter.hasNext()) { |
||||
final String address = fieldNamesIter.next(); |
||||
final JsonObject account = alloc.getJsonObject(address); |
||||
if (account.containsKey("precompiled") && !account.containsKey("balance")) { |
||||
fieldNamesIter.remove(); |
||||
} |
||||
} |
||||
|
||||
return chainParamsJson.encodePrettily(); |
||||
} |
||||
} |
@ -1,129 +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.ethereum.retesteth.methods; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; |
||||
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; |
||||
import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import com.google.common.base.Charsets; |
||||
import com.google.common.io.Resources; |
||||
import io.vertx.core.json.JsonObject; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
public class TestImportRawBlockTest { |
||||
private TestImportRawBlock test_importRawBlock; |
||||
private TestRewindToBlock test_rewindToBlock; |
||||
private RetestethContext context; |
||||
|
||||
@BeforeEach |
||||
public void setupClass() throws IOException { |
||||
context = new RetestethContext(); |
||||
test_importRawBlock = new TestImportRawBlock(context); |
||||
test_rewindToBlock = new TestRewindToBlock(context); |
||||
final TestSetChainParams test_setChainParams = new TestSetChainParams(context); |
||||
final String chainParamsJsonString = |
||||
Resources.toString( |
||||
TestSetChainParamsTest.class.getResource("multimpleBalanceInstructionChainParams.json"), |
||||
Charsets.UTF_8); |
||||
final JsonObject chainParamsJson = new JsonObject(chainParamsJsonString); |
||||
|
||||
final JsonRpcRequestContext request = |
||||
new JsonRpcRequestContext( |
||||
new JsonRpcRequest( |
||||
"2.0", TestSetChainParams.METHOD_NAME, new Object[] {chainParamsJson.getMap()})); |
||||
|
||||
assertThat(test_setChainParams.response(request)) |
||||
.isEqualTo(new JsonRpcSuccessResponse(null, true)); |
||||
} |
||||
|
||||
@Test |
||||
public void testMissingParent() { |
||||
final String rawBlockRLPString = |
||||
"0xf9045df901f9a0e38bef3dadb98e856ea82c7e9813b76a6ec8d9cf60694dd65d800a1669c1a1fda03770bba814f8cc5534ab5e40bdb3fe51866b537805c5577888091766e621fc13948888f1f195afa192cfee860698584c030f4c9db1a019ce64082807650d3d01ac60cd16a583e9472dcc0ccb8f39dd867e317cf025dda09735e49acaddb4d8338ed33df8dd006449b20b85e89e47224ac8ec8f7ea26071a0056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000483301fd28252088454c99c2142a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f86003018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0a7b7f2fa93025fc1e6aa18c1aa07c32a456439754e196cb74f2f7d12cf3e840da02078cf840fb25fc3d858b2a85b622f21be0588b5c5d81d433427f6470e06a4a7f901faf901f7a0f88512d9e022357594866c44ecaa2fc9cb48f34d1987e401109400761aeb898da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794bcde5374fce5edbc8e2a8697c15331677e6ebf0ba0fe87abb0d3ab38d4eb64405de03db5245b0d40c4b85d8a1b5028ada8643de2dba056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000002833007cf808454c9945142a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"; |
||||
|
||||
final JsonRpcRequestContext request = |
||||
new JsonRpcRequestContext( |
||||
new JsonRpcRequest( |
||||
"2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString})); |
||||
|
||||
final var response = test_importRawBlock.response(request); |
||||
assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR); |
||||
assertThat(((JsonRpcErrorResponse) response).getErrorType()) |
||||
.isEqualTo(RpcErrorType.BLOCK_IMPORT_ERROR); |
||||
} |
||||
|
||||
@Test |
||||
public void testBadBlock() { |
||||
final String rawBlockRLPString = "0xf9045df901f9a08"; |
||||
|
||||
final JsonRpcRequestContext request = |
||||
new JsonRpcRequestContext( |
||||
new JsonRpcRequest( |
||||
"2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString})); |
||||
|
||||
final var response = test_importRawBlock.response(request); |
||||
assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR); |
||||
assertThat(((JsonRpcErrorResponse) response).getErrorType()) |
||||
.isEqualTo(RpcErrorType.BLOCK_RLP_IMPORT_ERROR); |
||||
} |
||||
|
||||
@Test |
||||
public void testGoodBlock() { |
||||
final String rawBlockRLPString = |
||||
"0xf90262f901faa0e38bef3dadb98e856ea82c7e9813b76a6ec8d9cf60694dd65d800a1669c1a1fda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a06e6be3f633fe0399cb17a9d8238b988a39bd9ab3e0ac0820f4df705a1ee37536a06fb77a9ddaa64a8e161b643d05533a4093f2be900ad06279b1b56b3bcee3b979a04b33fa3c9c50b7b9a4500f5c0b1e71ab43362abc81c2cf31fd2b54acf7d750d8b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba83016b66845db7320980a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f860800a830249f094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0d42a045ac77a6d4676dd5fbc5104ed7471b6cef2465cfefaa52919b340f942a9a06e4d319aea79e45cde79d337e6edf849ceac505cab65dd41a572cab132d4dccac0"; |
||||
|
||||
final JsonRpcRequestContext request = |
||||
new JsonRpcRequestContext( |
||||
new JsonRpcRequest( |
||||
"2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString})); |
||||
|
||||
final var response = test_importRawBlock.response(request); |
||||
assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); |
||||
} |
||||
|
||||
@Test |
||||
public void testReimportExistingBlock() { |
||||
final String rawBlockRLPString = |
||||
"0xf90262f901faa0e38bef3dadb98e856ea82c7e9813b76a6ec8d9cf60694dd65d800a1669c1a1fda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a06e6be3f633fe0399cb17a9d8238b988a39bd9ab3e0ac0820f4df705a1ee37536a06fb77a9ddaa64a8e161b643d05533a4093f2be900ad06279b1b56b3bcee3b979a04b33fa3c9c50b7b9a4500f5c0b1e71ab43362abc81c2cf31fd2b54acf7d750d8b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba83016b66845db7320980a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f860800a830249f094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0d42a045ac77a6d4676dd5fbc5104ed7471b6cef2465cfefaa52919b340f942a9a06e4d319aea79e45cde79d337e6edf849ceac505cab65dd41a572cab132d4dccac0"; |
||||
|
||||
final JsonRpcRequestContext request = |
||||
new JsonRpcRequestContext( |
||||
new JsonRpcRequest( |
||||
"2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString})); |
||||
|
||||
final JsonRpcRequestContext requestRewind = |
||||
new JsonRpcRequestContext( |
||||
new JsonRpcRequest("2.0", TestRewindToBlock.METHOD_NAME, new Object[] {0L})); |
||||
|
||||
final var response = test_importRawBlock.response(request); |
||||
assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); |
||||
final var rewindResponse = test_rewindToBlock.response(requestRewind); |
||||
assertThat(rewindResponse.getType()).isEqualTo(RpcResponseType.SUCCESS); |
||||
final var reimportResponse = test_importRawBlock.response(request); |
||||
assertThat(reimportResponse.getType()).isEqualTo(RpcResponseType.SUCCESS); |
||||
|
||||
assertThat(context.getBlockchain().getChainHead().getHeight()).isEqualTo(1L); |
||||
} |
||||
} |
@ -1,115 +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.ethereum.retesteth.methods; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; |
||||
import org.hyperledger.besu.ethereum.core.BlockHeader; |
||||
import org.hyperledger.besu.ethereum.retesteth.RetestethContext; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import com.google.common.base.Charsets; |
||||
import com.google.common.io.Resources; |
||||
import io.vertx.core.json.JsonObject; |
||||
import org.apache.tuweni.units.bigints.UInt256; |
||||
import org.junit.jupiter.api.BeforeAll; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
public class TestSetChainParamsTest { |
||||
|
||||
private static RetestethContext context; |
||||
private static TestSetChainParams test_setChainParams; |
||||
|
||||
@BeforeAll |
||||
public static void setupClass() { |
||||
context = new RetestethContext(); |
||||
test_setChainParams = new TestSetChainParams(context); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidateGenesisImport() throws IOException { |
||||
final String chainParamsJsonString = |
||||
Resources.toString( |
||||
TestSetChainParamsTest.class.getResource("multimpleBalanceInstructionChainParams.json"), |
||||
Charsets.UTF_8); |
||||
final JsonObject chainParamsJson = new JsonObject(chainParamsJsonString); |
||||
|
||||
final JsonRpcRequestContext request = |
||||
new JsonRpcRequestContext( |
||||
new JsonRpcRequest( |
||||
"2.0", TestSetChainParams.METHOD_NAME, new Object[] {chainParamsJson.getMap()})); |
||||
|
||||
assertThat(test_setChainParams.response(request)) |
||||
.isEqualTo(new JsonRpcSuccessResponse(null, true)); |
||||
|
||||
final BlockHeader blockHeader = context.getBlockHeader(0); |
||||
|
||||
assertThat(blockHeader.getLogsBloom().toString()) |
||||
.isEqualTo( |
||||
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); |
||||
assertThat(blockHeader.getCoinbase().toString()) |
||||
.isEqualTo("0x8888f1f195afa192cfee860698584c030f4c9db1"); |
||||
assertThat(blockHeader.getDifficulty()).isEqualTo(UInt256.fromHexString("0x20000")); |
||||
assertThat(blockHeader.getExtraData().toHexString()).isEqualTo("0x42"); |
||||
assertThat(blockHeader.getGasLimit()).isEqualTo(3141592); |
||||
assertThat(blockHeader.getGasUsed()).isEqualTo(0); |
||||
assertThat(blockHeader.getMixHash().toString()) |
||||
.isEqualTo("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); |
||||
assertThat(blockHeader.getNonce()).isEqualTo(0x0102030405060708L); |
||||
assertThat(blockHeader.getNumber()).isEqualTo(0); |
||||
assertThat(blockHeader.getParentHash().toString()) |
||||
.isEqualTo("0x0000000000000000000000000000000000000000000000000000000000000000"); |
||||
assertThat(blockHeader.getReceiptsRoot().toString()) |
||||
.isEqualTo("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); |
||||
assertThat(blockHeader.getStateRoot().toString()) |
||||
.isEqualTo("0xf403922bfd555a9223f68fc755564004e20d78bb42aae647e867e3b23c48beba"); |
||||
assertThat(blockHeader.getTimestamp()).isEqualTo(0x54c98c81); |
||||
assertThat(blockHeader.getTransactionsRoot().toString()) |
||||
.isEqualTo("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); |
||||
assertThat(blockHeader.getOmmersHash().toString()) |
||||
.isEqualTo("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"); |
||||
} |
||||
|
||||
@Test |
||||
public void testValidate1559GenesisImport() throws IOException { |
||||
final String chainParamsJsonString = |
||||
Resources.toString( |
||||
TestSetChainParamsTest.class.getResource("1559ChainParams.json"), Charsets.UTF_8); |
||||
final JsonObject chainParamsJson = new JsonObject(chainParamsJsonString); |
||||
|
||||
final JsonRpcRequestContext request = |
||||
new JsonRpcRequestContext( |
||||
new JsonRpcRequest( |
||||
"2.0", TestSetChainParams.METHOD_NAME, new Object[] {chainParamsJson.getMap()})); |
||||
|
||||
assertThat(test_setChainParams.response(request)) |
||||
.isEqualTo(new JsonRpcSuccessResponse(null, true)); |
||||
|
||||
final BlockHeader blockHeader = context.getBlockHeader(0); |
||||
assertThat(blockHeader.getDifficulty()).isEqualTo(UInt256.fromHexString("0x20000")); |
||||
assertThat(blockHeader.getGasLimit()).isEqualTo(1234L); |
||||
assertThat(blockHeader.getBaseFee()).hasValue(Wei.of(12345L)); |
||||
assertThat(blockHeader.getExtraData().toHexString()).isEqualTo("0x00"); |
||||
assertThat(blockHeader.getTimestamp()).isEqualTo(0l); |
||||
assertThat(blockHeader.getNonce()).isEqualTo(0L); |
||||
assertThat(blockHeader.getMixHash().toHexString()) |
||||
.isEqualTo("0x0000000000000000000000000000000000000000000000000000000000000000"); |
||||
} |
||||
} |
@ -1,21 +0,0 @@ |
||||
{ |
||||
"genesis" : { |
||||
"author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
||||
"difficulty" : "0x020000", |
||||
"gasLimit" : "0x04d2", |
||||
"baseFeePerGas" : "0x3039", |
||||
"extraData" : "0x00", |
||||
"timestamp" : "0x00", |
||||
"nonce" : "0x0000000000000000", |
||||
"mixHash" : "0x0000000000000000000000000000000000000000000000000000000000000000" |
||||
}, |
||||
"params": { |
||||
"EIP150ForkBlock": "0x00", |
||||
"EIP158ForkBlock": "0x00", |
||||
"byzantiumForkBlock": "0x00", |
||||
"homesteadForkBlock": "0x00", |
||||
"londonForkBlock": "0x00" |
||||
}, |
||||
"sealEngine": "NoProof", |
||||
"accounts": {} |
||||
} |
@ -1,102 +0,0 @@ |
||||
{ |
||||
"accounts": { |
||||
"0x0000000000000000000000000000000000000001": { |
||||
"precompiled": { |
||||
"linear": { |
||||
"base": 3000, |
||||
"word": 0 |
||||
}, |
||||
"name": "ecrecover" |
||||
} |
||||
}, |
||||
"0x0000000000000000000000000000000000000002": { |
||||
"precompiled": { |
||||
"linear": { |
||||
"base": 60, |
||||
"word": 12 |
||||
}, |
||||
"name": "sha256" |
||||
} |
||||
}, |
||||
"0x0000000000000000000000000000000000000003": { |
||||
"precompiled": { |
||||
"linear": { |
||||
"base": 600, |
||||
"word": 120 |
||||
}, |
||||
"name": "sha256" |
||||
} |
||||
}, |
||||
"0x0000000000000000000000000000000000000004": { |
||||
"precompiled": { |
||||
"linear": { |
||||
"base": 15, |
||||
"word": 3 |
||||
}, |
||||
"name": "identity" |
||||
} |
||||
}, |
||||
"0x0000000000000000000000000000000000000005": { |
||||
"precompiled": { |
||||
"name": "modexp" |
||||
} |
||||
}, |
||||
"0x0000000000000000000000000000000000000006": { |
||||
"precompiled": { |
||||
"linear": { |
||||
"base": 500, |
||||
"word": 0 |
||||
}, |
||||
"name": "alt_bn128_G1_add" |
||||
} |
||||
}, |
||||
"0x0000000000000000000000000000000000000007": { |
||||
"precompiled": { |
||||
"linear": { |
||||
"base": 40000, |
||||
"word": 0 |
||||
}, |
||||
"name": "alt_bn128_G1_mul" |
||||
} |
||||
}, |
||||
"0x0000000000000000000000000000000000000008": { |
||||
"precompiled": { |
||||
"name": "alt_bn128_pairing_product" |
||||
} |
||||
}, |
||||
"0x095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
||||
"balance": "0x0186a0", |
||||
"code": "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0b31600055738888f1f195afa192cfee860698584c030f4c9db13160015573a94f5374fce5edbc8e2a8697c15331677e6ebf0b31600255738888f1f195afa192cfee860698584c030f4c9db13160035573095e7baea6a6c7c4c2dfeb977efac326af552d8731600555", |
||||
"nonce": "0x00", |
||||
"storage": {} |
||||
}, |
||||
"0x195e7baea6a6c7c4c2dfeb977efac326af552d87": { |
||||
"balance": "0x0186a0", |
||||
"code": "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0b31600055738888f1f195afa192cfee860698584c030f4c9db13160015573a94f5374fce5edbc8e2a8697c15331677e6ebf0b31600255738888f1f195afa192cfee860698584c030f4c9db13160035573095e7baea6a6c7c4c2dfeb977efac326af552d873160045573195e7baea6a6c7c4c2dfeb977efac326af552d8731600555", |
||||
"nonce": "0x00", |
||||
"storage": {} |
||||
}, |
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { |
||||
"balance": "0x1748721582", |
||||
"code": "0x", |
||||
"nonce": "0x00", |
||||
"storage": {} |
||||
} |
||||
}, |
||||
"genesis": { |
||||
"author": "0x8888f1f195afa192cfee860698584c030f4c9db1", |
||||
"difficulty": "0x020000", |
||||
"extraData": "0x42", |
||||
"gasLimit": "0x2fefd8", |
||||
"mixHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
||||
"nonce": "0x0102030405060708", |
||||
"timestamp": "0x54c98c81" |
||||
}, |
||||
"params": { |
||||
"EIP150ForkBlock": "0x00", |
||||
"EIP158ForkBlock": "0x00", |
||||
"byzantiumForkBlock": "0x00", |
||||
"homesteadForkBlock": "0x00" |
||||
}, |
||||
"sealEngine": "NoProof" |
||||
} |
@ -0,0 +1,66 @@ |
||||
/* |
||||
* Copyright contributors to 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.metrics; |
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse; |
||||
import static org.junit.jupiter.api.Assertions.assertTrue; |
||||
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; |
||||
|
||||
import java.util.Set; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
class MetricCategoryRegistryImplTest { |
||||
|
||||
@Test |
||||
void metricCategoryIsEnabledAndMetricsAreEnabled() { |
||||
final var registry = new MetricCategoryRegistryImpl(); |
||||
registry.addMetricCategory(BesuMetricCategory.BLOCKCHAIN); |
||||
final var metricsConfiguration = |
||||
MetricsConfiguration.builder() |
||||
.enabled(true) |
||||
.metricCategories(Set.of(BesuMetricCategory.BLOCKCHAIN)) |
||||
.build(); |
||||
registry.setMetricsConfiguration(metricsConfiguration); |
||||
assertTrue(registry.isMetricCategoryEnabled(BesuMetricCategory.BLOCKCHAIN)); |
||||
} |
||||
|
||||
@Test |
||||
void metricCategoryIsDisabledAndMetricsAreEnabled() { |
||||
final var registry = new MetricCategoryRegistryImpl(); |
||||
registry.addMetricCategory(BesuMetricCategory.ETHEREUM); |
||||
final var metricsConfiguration = |
||||
MetricsConfiguration.builder() |
||||
.enabled(true) |
||||
.metricCategories(Set.of(BesuMetricCategory.ETHEREUM)) |
||||
.build(); |
||||
registry.setMetricsConfiguration(metricsConfiguration); |
||||
assertFalse(registry.isMetricCategoryEnabled(BesuMetricCategory.BLOCKCHAIN)); |
||||
} |
||||
|
||||
@Test |
||||
void metricCategoryNotEnabledWhenMetricsAreDisabled() { |
||||
final var registry = new MetricCategoryRegistryImpl(); |
||||
registry.addMetricCategory(BesuMetricCategory.BLOCKCHAIN); |
||||
final var metricsConfiguration = |
||||
MetricsConfiguration.builder() |
||||
.enabled(false) |
||||
.metricCategories(Set.of(BesuMetricCategory.BLOCKCHAIN)) |
||||
.build(); |
||||
registry.setMetricsConfiguration(metricsConfiguration); |
||||
assertFalse(registry.isMetricCategoryEnabled(BesuMetricCategory.BLOCKCHAIN)); |
||||
} |
||||
} |
Loading…
Reference in new issue