mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-09 21:17:54 -05:00
Merge branch 'main' into zkbesu
This commit is contained in:
34
CHANGELOG.md
34
CHANGELOG.md
@@ -2,15 +2,6 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
- **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383)
|
||||
- `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433)
|
||||
|
||||
### Tests
|
||||
- Added a comprehensive test case to reproduce the bug and verify the fix for the `ClassCastException` in `DebugMetrics`. This ensures that complex, dynamically nested metric structures can be handled without errors.
|
||||
|
||||
## Next release
|
||||
|
||||
### Upcoming Breaking Changes
|
||||
|
||||
### Breaking Changes
|
||||
@@ -20,13 +11,16 @@
|
||||
- Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461)
|
||||
- Add pending block header to `TransactionEvaluationContext` plugin API [#7483](https://github.com/hyperledger/besu/pull/7483)
|
||||
- Add bootnode to holesky config [#7500](https://github.com/hyperledger/besu/pull/7500)
|
||||
- Implement engine_getClientVersionV1
|
||||
- Performance optimzation for ECMUL (1 of 2) [#7509](https://github.com/hyperledger/besu/pull/7509)
|
||||
- Performance optimzation for ECMUL (2 of 2) [#7543](https://github.com/hyperledger/besu/pull/7543)
|
||||
|
||||
### Bug fixes
|
||||
- Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318)
|
||||
- Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473)
|
||||
- Fix for `eth_gasPrice` could not retrieve block error [#7482](https://github.com/hyperledger/besu/pull/7482)
|
||||
|
||||
- Correctly drops messages that exceeds local message size limit [#5455](https://github.com/hyperledger/besu/pull/7507)
|
||||
- **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383)
|
||||
- `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433)
|
||||
|
||||
## 24.8.0
|
||||
|
||||
@@ -45,8 +39,7 @@
|
||||
- In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395)
|
||||
- Added support for tracing private transactions using `priv_traceTransaction` API. [#6161](https://github.com/hyperledger/besu/pull/6161)
|
||||
- Wrap WorldUpdater into EVMWorldupdater [#7434](https://github.com/hyperledger/besu/pull/7434)
|
||||
- Bump besu-native to 0.9.4 [#7456](https://github.com/hyperledger/besu/pull/7456)
|
||||
|
||||
- Bump besu-native to 0.9.4 [#7456](https://github.com/hyperledger/besu/pull/7456)=
|
||||
|
||||
### Bug fixes
|
||||
- Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430)
|
||||
@@ -54,6 +47,11 @@
|
||||
- Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431)
|
||||
- Fix Null pointer from DNS daemon [#7505](https://github.com/hyperledger/besu/issues/7505)
|
||||
|
||||
### Download Links
|
||||
https://github.com/hyperledger/besu/releases/tag/24.8.0
|
||||
https://github.com/hyperledger/besu/releases/download/24.8.0/besu-24.8.0.tar.gz / sha256 9671157a623fb94005357bc409d1697a0d62bb6fd434b1733441bb301a9534a4
|
||||
https://github.com/hyperledger/besu/releases/download/24.8.0/besu-24.8.0.zip / sha256 9ee217d2188e8da89002c3f42e4f85f89aab782e9512bd03520296f0a4dcdd90
|
||||
|
||||
## 24.7.1
|
||||
|
||||
### Breaking Changes
|
||||
@@ -89,6 +87,11 @@
|
||||
- Add 30 second timeout to trie log pruner preload [#7365](https://github.com/hyperledger/besu/pull/7365)
|
||||
- Avoid executing pruner preload during trie log subcommands [#7366](https://github.com/hyperledger/besu/pull/7366)
|
||||
|
||||
### Download Links
|
||||
https://github.com/hyperledger/besu/releases/tag/24.7.1
|
||||
https://github.com/hyperledger/besu/releases/download/24.7.1/besu-24.7.1.tar.gz / sha256 59ac352a86fd887225737a5fe4dad1742347edd3c3fbed98b079177e4ea8d544
|
||||
https://github.com/hyperledger/besu/releases/download/24.7.1/besu-24.7.1.zip / sha256 e616f8100f026a71a146a33847b40257c279b38085b17bb991df045cccb6f832
|
||||
|
||||
## 24.7.0
|
||||
|
||||
### Upcoming Breaking Changes
|
||||
@@ -121,6 +124,11 @@
|
||||
- Fix "Could not confirm best peer had pivot block" [#7109](https://github.com/hyperledger/besu/issues/7109)
|
||||
- Fix "Chain Download Halt" [#6884](https://github.com/hyperledger/besu/issues/6884)
|
||||
|
||||
### Download Links
|
||||
https://github.com/hyperledger/besu/releases/tag/24.7.0
|
||||
https://github.com/hyperledger/besu/releases/download/24.7.0/besu-24.7.0.tar.gz / sha256 96cf47defd1d8c10bfc22634e53e3d640eaa81ef58cb0808e5f4265998979530
|
||||
https://github.com/hyperledger/besu/releases/download/24.7.0/besu-24.7.0.zip / sha256 7e92e2eb469be197af8c8ca7ac494e7a2e7ee91cbdb02d99ff87fb5209e0c2a0
|
||||
|
||||
|
||||
|
||||
## 24.6.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## Pre-requisites
|
||||
* [Truffle](https://truffleframework.com/) installed
|
||||
* [Truffle](https://archive.trufflesuite.com/truffle/) installed
|
||||
```
|
||||
npm install -g truffle
|
||||
```
|
||||
|
||||
@@ -17,8 +17,6 @@ package org.hyperledger.besu;
|
||||
import org.hyperledger.besu.util.platform.PlatformDetector;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Represent Besu information such as version, OS etc. Used with --version option and during Besu
|
||||
@@ -26,29 +24,9 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public final class BesuInfo {
|
||||
private static final String CLIENT = "besu";
|
||||
private static final String VERSION = BesuInfo.class.getPackage().getImplementationVersion();
|
||||
private static final String OS = PlatformDetector.getOS();
|
||||
private static final String VM = PlatformDetector.getVM();
|
||||
private static final String VERSION;
|
||||
private static final String COMMIT;
|
||||
|
||||
static {
|
||||
String projectVersion = BesuInfo.class.getPackage().getImplementationVersion();
|
||||
if (projectVersion == null) {
|
||||
// protect against unset project version (e.g. unit tests being run, etc)
|
||||
VERSION = null;
|
||||
COMMIT = null;
|
||||
} else {
|
||||
Pattern pattern =
|
||||
Pattern.compile("(?<version>\\d+\\.\\d+\\.?\\d?-?\\w*)-(?<commit>[0-9a-fA-F]{8})");
|
||||
Matcher matcher = pattern.matcher(projectVersion);
|
||||
if (matcher.find()) {
|
||||
VERSION = matcher.group("version");
|
||||
COMMIT = matcher.group("commit");
|
||||
} else {
|
||||
throw new RuntimeException("Invalid project version: " + projectVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BesuInfo() {}
|
||||
|
||||
@@ -68,7 +46,7 @@ public final class BesuInfo {
|
||||
* or "besu/v23.1.0/osx-aarch_64/corretto-java-19"
|
||||
*/
|
||||
public static String version() {
|
||||
return String.format("%s/v%s-%s/%s/%s", CLIENT, VERSION, COMMIT, OS, VM);
|
||||
return String.format("%s/v%s/%s/%s", CLIENT, VERSION, OS, VM);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,18 +57,7 @@ public final class BesuInfo {
|
||||
*/
|
||||
public static String nodeName(final Optional<String> maybeIdentity) {
|
||||
return maybeIdentity
|
||||
.map(
|
||||
identity ->
|
||||
String.format("%s/%s/v%s-%s/%s/%s", CLIENT, identity, VERSION, COMMIT, OS, VM))
|
||||
.map(identity -> String.format("%s/%s/v%s/%s/%s", CLIENT, identity, VERSION, OS, VM))
|
||||
.orElse(version());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the commit hash for this besu version
|
||||
*
|
||||
* @return the commit hash for this besu version
|
||||
*/
|
||||
public static String commit() {
|
||||
return COMMIT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1291,8 +1291,6 @@ public class RunnerBuilder {
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
BesuInfo.nodeName(identityString),
|
||||
BesuInfo.shortVersion(),
|
||||
BesuInfo.commit(),
|
||||
ethNetworkConfig.networkId(),
|
||||
besuController.getGenesisConfigOptions(),
|
||||
network,
|
||||
|
||||
@@ -16,6 +16,7 @@ package org.hyperledger.besu.controller;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.hyperledger.besu.config.BftConfigOptions;
|
||||
import org.hyperledger.besu.config.BftFork;
|
||||
import org.hyperledger.besu.config.QbftConfigOptions;
|
||||
import org.hyperledger.besu.config.QbftFork;
|
||||
@@ -103,6 +104,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
|
||||
private ForksSchedule<QbftConfigOptions> qbftForksSchedule;
|
||||
private ValidatorPeers peers;
|
||||
private TransactionValidatorProvider transactionValidatorProvider;
|
||||
private BftConfigOptions bftConfigOptions;
|
||||
|
||||
/** Default Constructor. */
|
||||
public QbftBesuControllerBuilder() {}
|
||||
@@ -120,6 +122,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
|
||||
qbftConfig = genesisConfigOptions.getQbftConfigOptions();
|
||||
bftEventQueue = new BftEventQueue(qbftConfig.getMessageQueueLimit());
|
||||
qbftForksSchedule = QbftForksSchedulesFactory.create(genesisConfigOptions);
|
||||
bftConfigOptions = qbftConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -132,7 +135,8 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
miningParameters,
|
||||
createReadOnlyValidatorProvider(protocolContext.getBlockchain()));
|
||||
createReadOnlyValidatorProvider(protocolContext.getBlockchain()),
|
||||
bftConfigOptions);
|
||||
}
|
||||
|
||||
private ValidatorProvider createReadOnlyValidatorProvider(final Blockchain blockchain) {
|
||||
|
||||
@@ -33,8 +33,7 @@ public final class BesuInfoTest {
|
||||
*/
|
||||
@Test
|
||||
public void versionStringIsEthstatsFriendly() {
|
||||
assertThat(BesuInfo.version())
|
||||
.matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+");
|
||||
assertThat(BesuInfo.version()).matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +45,7 @@ public final class BesuInfoTest {
|
||||
@Test
|
||||
public void noIdentityNodeNameIsEthstatsFriendly() {
|
||||
assertThat(BesuInfo.nodeName(Optional.empty()))
|
||||
.matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+");
|
||||
.matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,6 +58,6 @@ public final class BesuInfoTest {
|
||||
@Test
|
||||
public void userIdentityNodeNameIsEthstatsFriendly() {
|
||||
assertThat(BesuInfo.nodeName(Optional.of("TestUserIdentity")))
|
||||
.matches("[^/]+/[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+");
|
||||
.matches("[^/]+/[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ import org.hyperledger.besu.plugin.data.SyncStatus;
|
||||
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
import org.hyperledger.besu.testutil.TestClock;
|
||||
import org.hyperledger.besu.util.number.ByteUnits;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.time.ZoneId;
|
||||
@@ -154,7 +155,7 @@ public class BesuEventsImplTest {
|
||||
.when(mockWorldStateArchive.getMutable(any(), anyBoolean()))
|
||||
.thenReturn(Optional.of(mockWorldState));
|
||||
|
||||
blockBroadcaster = new BlockBroadcaster(mockEthContext);
|
||||
blockBroadcaster = new BlockBroadcaster(mockEthContext, 10 * ByteUnits.MEGABYTE);
|
||||
syncState = new SyncState(blockchain, mockEthPeers);
|
||||
TransactionPoolConfiguration txPoolConfig =
|
||||
ImmutableTransactionPoolConfiguration.builder()
|
||||
|
||||
33
build.gradle
33
build.gradle
@@ -32,10 +32,6 @@ plugins {
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
tasks.register('spotlessCheckFast') {
|
||||
dependsOn subprojects.collect { it.tasks.withType(com.diffplug.gradle.spotless.SpotlessCheck) }
|
||||
}
|
||||
|
||||
if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_21)) {
|
||||
throw new GradleException("Java 21 or later is required to build Besu.\n" +
|
||||
" Detected version ${JavaVersion.current()}")
|
||||
@@ -45,12 +41,15 @@ group = 'io.consensys.linea-besu'
|
||||
|
||||
defaultTasks 'build', 'checkLicense', 'javadoc'
|
||||
|
||||
def buildAliases = ['dev': [
|
||||
def buildAliases = [
|
||||
'dev': [
|
||||
'spotlessApply',
|
||||
'build',
|
||||
'checkLicense',
|
||||
'javadoc'
|
||||
]]
|
||||
],
|
||||
'build': ['spotlessCheck', 'build']
|
||||
]
|
||||
|
||||
def expandedTaskList = []
|
||||
gradle.startParameter.taskNames.each {
|
||||
@@ -423,12 +422,6 @@ allprojects {
|
||||
options.addStringOption('Xwerror', '-html5')
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
plugins.withType(JavaPlugin) {
|
||||
tasks.withType(JavaCompile) {
|
||||
it.dependsOn(rootProject.tasks.named('spotlessCheckFast'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task deploy() {}
|
||||
@@ -452,7 +445,7 @@ task checkMavenCoordinateCollisions {
|
||||
|
||||
tasks.register('checkPluginAPIChanges', DefaultTask) {}
|
||||
checkPluginAPIChanges.dependsOn(':plugin-api:checkAPIChanges')
|
||||
check.dependsOn('checkPluginAPIChanges', 'checkMavenCoordinateCollisions', 'spotlessCheckFast')
|
||||
check.dependsOn('checkPluginAPIChanges', 'checkMavenCoordinateCollisions')
|
||||
|
||||
subprojects {
|
||||
|
||||
@@ -804,7 +797,7 @@ task distDocker {
|
||||
dockerPlatform = "--platform ${project.getProperty('docker-platform')}"
|
||||
println "Building for platform ${project.getProperty('docker-platform')}"
|
||||
}
|
||||
def gitDetails = getGitCommitDetails()
|
||||
def gitDetails = getGitCommitDetails(7)
|
||||
executable shell
|
||||
workingDir dockerBuildDir
|
||||
args "-c", "docker buildx build ${dockerPlatform} --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${gitDetails.hash} -t ${image} --push ."
|
||||
@@ -972,13 +965,17 @@ def buildTime() {
|
||||
def calculateVersion() {
|
||||
// Regex pattern for basic calendar versioning, with provision to omit patch rev
|
||||
def calVerPattern = ~/\d+\.\d+(\.\d+)?(-.*)?/
|
||||
def gitDetails = getGitCommitDetails() // Adjust length as needed
|
||||
|
||||
if (project.hasProperty('version') && (project.version =~ calVerPattern)) {
|
||||
println("Generating project version using supplied version: ${project.version}-${gitDetails.hash}")
|
||||
return "${project.version}-${gitDetails.hash}"
|
||||
if (project.hasProperty('versionappendcommit') && project.versionappendcommit == "true") {
|
||||
def gitDetails = getGitCommitDetails(7) // Adjust length as needed
|
||||
return "${project.version}-${gitDetails.hash}"
|
||||
}
|
||||
return "${project.version}"
|
||||
} else {
|
||||
// If no version is supplied or it doesn't match the semantic versioning, calculate from git
|
||||
println("Generating project version using date (${gitDetails.date}-develop-${gitDetails.hash}), as supplied version is not semver: ${project.version}")
|
||||
println("Generating project version as supplied is version not semver: ${project.version}")
|
||||
def gitDetails = getGitCommitDetails(7) // Adjust length as needed
|
||||
return "${gitDetails.date}-develop-${gitDetails.hash}"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
*/
|
||||
package org.hyperledger.besu.consensus.qbft.jsonrpc;
|
||||
|
||||
import org.hyperledger.besu.config.BftConfigOptions;
|
||||
import org.hyperledger.besu.consensus.common.BlockInterface;
|
||||
import org.hyperledger.besu.consensus.common.bft.BftContext;
|
||||
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
||||
import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftDiscardValidatorVote;
|
||||
import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetPendingVotes;
|
||||
import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetRequestTimeoutSeconds;
|
||||
import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetSignerMetrics;
|
||||
import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetValidatorsByBlockHash;
|
||||
import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetValidatorsByBlockNumber;
|
||||
@@ -40,6 +42,7 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
private final ValidatorProvider readOnlyValidatorProvider;
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final MiningParameters miningParameters;
|
||||
private final BftConfigOptions bftConfig;
|
||||
|
||||
/**
|
||||
* Instantiates a new Qbft json rpc methods.
|
||||
@@ -48,16 +51,19 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
* @param protocolSchedule the protocol schedule
|
||||
* @param miningParameters the mining parameters
|
||||
* @param readOnlyValidatorProvider the read only validator provider
|
||||
* @param bftConfig the BFT config options, containing QBFT-specific settings
|
||||
*/
|
||||
public QbftJsonRpcMethods(
|
||||
final ProtocolContext context,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final MiningParameters miningParameters,
|
||||
final ValidatorProvider readOnlyValidatorProvider) {
|
||||
final ValidatorProvider readOnlyValidatorProvider,
|
||||
final BftConfigOptions bftConfig) {
|
||||
this.context = context;
|
||||
this.readOnlyValidatorProvider = readOnlyValidatorProvider;
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.miningParameters = miningParameters;
|
||||
this.bftConfig = bftConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,12 +83,16 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
final BlockInterface blockInterface = bftContext.getBlockInterface();
|
||||
final ValidatorProvider validatorProvider = bftContext.getValidatorProvider();
|
||||
|
||||
return mapOf(
|
||||
new QbftProposeValidatorVote(validatorProvider),
|
||||
new QbftGetValidatorsByBlockNumber(blockchainQueries, readOnlyValidatorProvider),
|
||||
new QbftDiscardValidatorVote(validatorProvider),
|
||||
new QbftGetValidatorsByBlockHash(context.getBlockchain(), readOnlyValidatorProvider),
|
||||
new QbftGetSignerMetrics(readOnlyValidatorProvider, blockInterface, blockchainQueries),
|
||||
new QbftGetPendingVotes(validatorProvider));
|
||||
Map<String, JsonRpcMethod> methods =
|
||||
mapOf(
|
||||
new QbftProposeValidatorVote(validatorProvider),
|
||||
new QbftGetValidatorsByBlockNumber(blockchainQueries, readOnlyValidatorProvider),
|
||||
new QbftDiscardValidatorVote(validatorProvider),
|
||||
new QbftGetValidatorsByBlockHash(context.getBlockchain(), readOnlyValidatorProvider),
|
||||
new QbftGetSignerMetrics(readOnlyValidatorProvider, blockInterface, blockchainQueries),
|
||||
new QbftGetPendingVotes(validatorProvider),
|
||||
new QbftGetRequestTimeoutSeconds(bftConfig));
|
||||
|
||||
return methods;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.consensus.qbft.jsonrpc.methods;
|
||||
|
||||
import org.hyperledger.besu.config.BftConfigOptions;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
|
||||
/**
|
||||
* Implements the qbft_getRequestTimeoutSeconds RPC method to retrieve the QBFT request timeout in
|
||||
* seconds.
|
||||
*/
|
||||
public class QbftGetRequestTimeoutSeconds implements JsonRpcMethod {
|
||||
|
||||
private final BftConfigOptions bftConfig;
|
||||
|
||||
/**
|
||||
* Constructs a new QbftGetRequestTimeoutSeconds instance.
|
||||
*
|
||||
* @param bftConfig The BFT configuration options
|
||||
*/
|
||||
public QbftGetRequestTimeoutSeconds(final BftConfigOptions bftConfig) {
|
||||
this.bftConfig = bftConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return RpcMethod.QBFT_GET_REQUEST_TIMEOUT_SECONDS.getMethodName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
|
||||
return new JsonRpcSuccessResponse(
|
||||
requestContext.getRequest().getId(), bftConfig.getRequestTimeoutSeconds());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.consensus.qbft.jsonrpc.methods;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.BftConfigOptions;
|
||||
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.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
|
||||
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 QbftGetRequestTimeoutSecondsTest {
|
||||
|
||||
private static final String JSON_RPC_VERSION = "2.0";
|
||||
private static final String METHOD_NAME = "qbft_getRequestTimeoutSeconds";
|
||||
|
||||
@Mock private BftConfigOptions bftConfigOptions;
|
||||
|
||||
private QbftGetRequestTimeoutSeconds method;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
this.method = new QbftGetRequestTimeoutSeconds(bftConfigOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnCorrectMethodName() {
|
||||
assertThat(method.getName()).isEqualTo(METHOD_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnCorrectRequestTimeout() {
|
||||
final int expectedTimeout = 5;
|
||||
when(bftConfigOptions.getRequestTimeoutSeconds()).thenReturn(expectedTimeout);
|
||||
JsonRpcRequestContext request = requestWithParams();
|
||||
|
||||
JsonRpcResponse response = method.response(request);
|
||||
|
||||
assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class);
|
||||
JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response;
|
||||
assertThat(successResponse.getResult()).isEqualTo(expectedTimeout);
|
||||
}
|
||||
|
||||
private JsonRpcRequestContext requestWithParams(final Object... params) {
|
||||
return new JsonRpcRequestContext(new JsonRpcRequest(JSON_RPC_VERSION, METHOD_NAME, params));
|
||||
}
|
||||
}
|
||||
@@ -64,9 +64,7 @@ import io.vertx.core.VertxOptions;
|
||||
/** Provides a facade to construct the JSON-RPC component. */
|
||||
public class JsonRpcTestMethodsFactory {
|
||||
|
||||
private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
private static final String CLIENT_VERSION = "0.1.0";
|
||||
private static final String CLIENT_COMMIT = "12345678";
|
||||
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
private static final BigInteger NETWORK_ID = BigInteger.valueOf(123);
|
||||
|
||||
private final BlockchainImporter importer;
|
||||
@@ -177,9 +175,7 @@ public class JsonRpcTestMethodsFactory {
|
||||
|
||||
return new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
NETWORK_ID,
|
||||
new StubGenesisConfigOptions(),
|
||||
peerDiscovery,
|
||||
|
||||
@@ -63,7 +63,6 @@ public enum RpcMethod {
|
||||
ENGINE_FORKCHOICE_UPDATED_V2("engine_forkchoiceUpdatedV2"),
|
||||
ENGINE_FORKCHOICE_UPDATED_V3("engine_forkchoiceUpdatedV3"),
|
||||
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION("engine_exchangeTransitionConfigurationV1"),
|
||||
ENGINE_GET_CLIENT_VERSION_V1("engine_getClientVersionV1"),
|
||||
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1("engine_getPayloadBodiesByHashV1"),
|
||||
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1("engine_getPayloadBodiesByRangeV1"),
|
||||
ENGINE_EXCHANGE_CAPABILITIES("engine_exchangeCapabilities"),
|
||||
@@ -153,6 +152,7 @@ public enum RpcMethod {
|
||||
QBFT_GET_VALIDATORS_BY_BLOCK_NUMBER("qbft_getValidatorsByBlockNumber"),
|
||||
QBFT_PROPOSE_VALIDATOR_VOTE("qbft_proposeValidatorVote"),
|
||||
QBFT_GET_SIGNER_METRICS("qbft_getSignerMetrics"),
|
||||
QBFT_GET_REQUEST_TIMEOUT_SECONDS("qbft_getRequestTimeoutSeconds"),
|
||||
MINER_CHANGE_TARGET_GAS_LIMIT("miner_changeTargetGasLimit"),
|
||||
MINER_SET_COINBASE("miner_setCoinbase"),
|
||||
MINER_SET_ETHERBASE("miner_setEtherbase"),
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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.jsonrpc.internal.methods.engine;
|
||||
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1;
|
||||
|
||||
import io.vertx.core.Vertx;
|
||||
|
||||
public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod {
|
||||
private static final String ENGINE_CLIENT_CODE = "BU";
|
||||
private static final String ENGINE_CLIENT_NAME = "Besu";
|
||||
|
||||
private final String clientVersion;
|
||||
private final String commit;
|
||||
|
||||
public EngineGetClientVersionV1(
|
||||
final Vertx vertx,
|
||||
final ProtocolContext protocolContext,
|
||||
final EngineCallListener engineCallListener,
|
||||
final String clientVersion,
|
||||
final String commit) {
|
||||
super(vertx, protocolContext, engineCallListener);
|
||||
this.clientVersion = clientVersion;
|
||||
this.commit = commit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return RpcMethod.ENGINE_GET_CLIENT_VERSION_V1.getMethodName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) {
|
||||
return new JsonRpcSuccessResponse(
|
||||
request.getRequest().getId(),
|
||||
new EngineGetClientVersionResultV1(
|
||||
ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, commit));
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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.jsonrpc.internal.results;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
|
||||
public class EngineGetClientVersionResultV1 {
|
||||
private final String code;
|
||||
private final String name;
|
||||
private final String version;
|
||||
private final String commit;
|
||||
|
||||
public EngineGetClientVersionResultV1(
|
||||
final String code, final String name, final String version, final String commit) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
this.commit = commit;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "code")
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "name")
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "version")
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "commit")
|
||||
public String getCommit() {
|
||||
return commit;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineE
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV1;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV2;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV3;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetClientVersionV1;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByHashV1;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByRangeV1;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV1;
|
||||
@@ -58,17 +57,13 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
private final ProtocolContext protocolContext;
|
||||
private final EthPeers ethPeers;
|
||||
private final Vertx consensusEngineServer;
|
||||
private final String clientVersion;
|
||||
private final String commit;
|
||||
|
||||
ExecutionEngineJsonRpcMethods(
|
||||
final MiningCoordinator miningCoordinator,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final ProtocolContext protocolContext,
|
||||
final EthPeers ethPeers,
|
||||
final Vertx consensusEngineServer,
|
||||
final String clientVersion,
|
||||
final String commit) {
|
||||
final Vertx consensusEngineServer) {
|
||||
this.mergeCoordinator =
|
||||
Optional.ofNullable(miningCoordinator)
|
||||
.filter(mc -> mc.isCompatibleWithEngineApi())
|
||||
@@ -77,8 +72,6 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
this.protocolContext = protocolContext;
|
||||
this.ethPeers = ethPeers;
|
||||
this.consensusEngineServer = consensusEngineServer;
|
||||
this.clientVersion = clientVersion;
|
||||
this.commit = commit;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,9 +147,7 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
new EngineExchangeCapabilities(
|
||||
consensusEngineServer, protocolContext, engineQosTimer),
|
||||
new EnginePreparePayloadDebug(
|
||||
consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()),
|
||||
new EngineGetClientVersionV1(
|
||||
consensusEngineServer, protocolContext, engineQosTimer, clientVersion, commit)));
|
||||
consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get())));
|
||||
|
||||
if (protocolSchedule.anyMatch(p -> p.spec().getName().equalsIgnoreCase("cancun"))) {
|
||||
executionEngineApisSupported.add(
|
||||
|
||||
@@ -54,9 +54,7 @@ import io.vertx.core.Vertx;
|
||||
public class JsonRpcMethodsFactory {
|
||||
|
||||
public Map<String, JsonRpcMethod> methods(
|
||||
final String clientNodeName,
|
||||
final String clientVersion,
|
||||
final String commit,
|
||||
final BigInteger networkId,
|
||||
final GenesisConfigOptions genesisConfigOptions,
|
||||
final P2PNetwork p2pNetwork,
|
||||
@@ -91,7 +89,7 @@ public class JsonRpcMethodsFactory {
|
||||
final List<JsonRpcMethods> availableApiGroups =
|
||||
List.of(
|
||||
new AdminJsonRpcMethods(
|
||||
clientNodeName,
|
||||
clientVersion,
|
||||
networkId,
|
||||
genesisConfigOptions,
|
||||
p2pNetwork,
|
||||
@@ -117,9 +115,7 @@ public class JsonRpcMethodsFactory {
|
||||
protocolSchedule,
|
||||
protocolContext,
|
||||
ethPeers,
|
||||
consensusEngineServer,
|
||||
clientVersion,
|
||||
commit),
|
||||
consensusEngineServer),
|
||||
new EthJsonRpcMethods(
|
||||
blockchainQueries,
|
||||
synchronizer,
|
||||
@@ -145,7 +141,7 @@ public class JsonRpcMethodsFactory {
|
||||
filterManager),
|
||||
new PrivxJsonRpcMethods(
|
||||
blockchainQueries, protocolSchedule, transactionPool, privacyParameters),
|
||||
new Web3JsonRpcMethods(clientNodeName),
|
||||
new Web3JsonRpcMethods(clientVersion),
|
||||
new TraceJsonRpcMethods(
|
||||
blockchainQueries, protocolSchedule, protocolContext, apiConfiguration),
|
||||
new TxPoolJsonRpcMethods(transactionPool),
|
||||
|
||||
@@ -75,9 +75,7 @@ public abstract class AbstractJsonRpcHttpServiceTest {
|
||||
|
||||
protected BlockchainSetupUtil blockchainSetupUtil;
|
||||
|
||||
protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
protected static final String CLIENT_VERSION = "0.1.0";
|
||||
protected static final String CLIENT_COMMIT = "12345678";
|
||||
protected static String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
protected static final BigInteger NETWORK_ID = BigInteger.valueOf(123);
|
||||
protected static final Collection<String> JSON_RPC_APIS =
|
||||
Arrays.asList(
|
||||
@@ -170,9 +168,7 @@ public abstract class AbstractJsonRpcHttpServiceTest {
|
||||
|
||||
return new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
NETWORK_ID,
|
||||
new StubGenesisConfigOptions(),
|
||||
peerDiscoveryMock,
|
||||
|
||||
@@ -58,13 +58,13 @@ public class AdminJsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
final List<EthPeer> peerList = new ArrayList<>();
|
||||
final PeerInfo info1 =
|
||||
new PeerInfo(
|
||||
4, CLIENT_NODE_NAME, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1)));
|
||||
4, CLIENT_VERSION, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1)));
|
||||
final PeerInfo info2 =
|
||||
new PeerInfo(
|
||||
4, CLIENT_NODE_NAME, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2)));
|
||||
4, CLIENT_VERSION, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2)));
|
||||
final PeerInfo info3 =
|
||||
new PeerInfo(
|
||||
4, CLIENT_NODE_NAME, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3)));
|
||||
4, CLIENT_VERSION, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3)));
|
||||
final InetSocketAddress addr30301 = new InetSocketAddress("localhost", 30301);
|
||||
final InetSocketAddress addr30302 = new InetSocketAddress("localhost", 30302);
|
||||
final InetSocketAddress addr60301 = new InetSocketAddress("localhost", 60301);
|
||||
|
||||
@@ -79,9 +79,7 @@ public class JsonRpcHttpServiceHostAllowlistTest {
|
||||
private static OkHttpClient client;
|
||||
private static String baseUrl;
|
||||
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
private static final String CLIENT_VERSION = "0.1.0";
|
||||
private static final String CLIENT_COMMIT = "12345678";
|
||||
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
private static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
|
||||
|
||||
private final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig();
|
||||
@@ -102,9 +100,7 @@ public class JsonRpcHttpServiceHostAllowlistTest {
|
||||
rpcMethods =
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
CHAIN_ID,
|
||||
new StubGenesisConfigOptions(),
|
||||
peerDiscoveryMock,
|
||||
|
||||
@@ -100,9 +100,7 @@ public class JsonRpcHttpServiceLoginTest {
|
||||
protected static OkHttpClient client;
|
||||
protected static String baseUrl;
|
||||
protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
protected static final String CLIENT_VERSION = "0.1.0";
|
||||
protected static final String CLIENT_COMMIT = "12345678";
|
||||
protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
|
||||
protected static P2PNetwork peerDiscoveryMock;
|
||||
protected static BlockchainQueries blockchainQueries;
|
||||
@@ -133,9 +131,7 @@ public class JsonRpcHttpServiceLoginTest {
|
||||
rpcMethods =
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
CHAIN_ID,
|
||||
genesisConfigOptions,
|
||||
peerDiscoveryMock,
|
||||
|
||||
@@ -94,9 +94,7 @@ public class JsonRpcHttpServiceRpcApisTest {
|
||||
private JsonRpcHttpService service;
|
||||
private static String baseUrl;
|
||||
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
private static final String CLIENT_VERSION = "0.1.0";
|
||||
private static final String CLIENT_COMMIT = "12345678";
|
||||
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
private static final BigInteger NETWORK_ID = BigInteger.valueOf(123);
|
||||
private JsonRpcConfiguration configuration;
|
||||
private static final List<String> netServices =
|
||||
@@ -204,9 +202,7 @@ public class JsonRpcHttpServiceRpcApisTest {
|
||||
final Map<String, JsonRpcMethod> rpcMethods =
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
NETWORK_ID,
|
||||
new StubGenesisConfigOptions(),
|
||||
mock(P2PNetwork.class),
|
||||
@@ -314,9 +310,7 @@ public class JsonRpcHttpServiceRpcApisTest {
|
||||
final Map<String, JsonRpcMethod> rpcMethods =
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
NETWORK_ID,
|
||||
new StubGenesisConfigOptions(),
|
||||
p2pNetwork,
|
||||
|
||||
@@ -202,7 +202,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
testHelper.assertValidJsonRpcResult(json, id);
|
||||
// Check result
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1127,7 +1127,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
testHelper.assertValidJsonRpcResult(json, id);
|
||||
// Check result
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1143,7 +1143,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
final JsonObject json = new JsonObject(resp.body().string());
|
||||
testHelper.assertValidJsonRpcResult(json, id);
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1175,7 +1175,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
testHelper.assertValidJsonRpcResult(json, null);
|
||||
// Check result
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1197,7 +1197,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
testHelper.assertValidJsonRpcResult(json, id);
|
||||
// Check result
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1218,7 +1218,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
testHelper.assertValidJsonRpcResult(json, id);
|
||||
// Check result
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1242,7 +1242,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
testHelper.assertValidJsonRpcResult(json, id);
|
||||
// Check result
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1268,7 +1268,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
testHelper.assertValidJsonRpcResult(json, id);
|
||||
// Check result
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1289,7 +1289,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
testHelper.assertValidJsonRpcResult(json, id);
|
||||
// Check result
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1353,7 +1353,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
final JsonObject json = new JsonObject(resp.body().string());
|
||||
testHelper.assertValidJsonRpcResult(json, id);
|
||||
final String result = json.getString("result");
|
||||
assertThat(result).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(result).isEqualTo(CLIENT_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1485,7 +1485,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
// Check result web3_clientVersion
|
||||
final JsonObject jsonClientVersion = responses.get(clientVersionRequestId);
|
||||
testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId);
|
||||
assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION);
|
||||
|
||||
// Check result unknown method
|
||||
final JsonObject jsonError = responses.get(brokenRequestId);
|
||||
@@ -1540,7 +1540,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
// Check result web3_clientVersion
|
||||
final JsonObject jsonClientVersion = responses.get(clientVersionRequestId);
|
||||
testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId);
|
||||
assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION);
|
||||
|
||||
// Check invalid request
|
||||
final JsonObject jsonError = responses.get(invalidId);
|
||||
@@ -1605,7 +1605,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
|
||||
// Check result web3_clientVersion
|
||||
final JsonObject jsonClientVersion = responses.get(clientVersionRequestId);
|
||||
testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId);
|
||||
assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME);
|
||||
assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION);
|
||||
|
||||
// Check result net_version
|
||||
final JsonObject jsonNetVersion = responses.get(netVersionRequestId);
|
||||
|
||||
@@ -78,9 +78,7 @@ public class JsonRpcHttpServiceTestBase {
|
||||
protected static OkHttpClient client;
|
||||
protected static String baseUrl;
|
||||
protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
protected static final String CLIENT_VERSION = "0.1.0";
|
||||
protected static final String CLIENT_COMMIT = "12345678";
|
||||
protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
|
||||
protected static P2PNetwork peerDiscoveryMock;
|
||||
protected static EthPeers ethPeersMock;
|
||||
@@ -110,9 +108,7 @@ public class JsonRpcHttpServiceTestBase {
|
||||
rpcMethods =
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
CHAIN_ID,
|
||||
new StubGenesisConfigOptions(),
|
||||
peerDiscoveryMock,
|
||||
|
||||
@@ -85,9 +85,7 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
|
||||
protected static final Vertx vertx = Vertx.vertx();
|
||||
|
||||
private static final String JSON_HEADER = "application/json; charset=utf-8";
|
||||
private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
private static final String CLIENT_VERSION = "0.1.0";
|
||||
private static final String CLIENT_COMMIT = "12345678";
|
||||
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
private static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
|
||||
|
||||
private static final NatService natService = new NatService(Optional.empty());
|
||||
@@ -116,9 +114,7 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
|
||||
rpcMethods =
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
CHAIN_ID,
|
||||
new StubGenesisConfigOptions(),
|
||||
peerDiscoveryMock,
|
||||
|
||||
@@ -75,9 +75,7 @@ class JsonRpcHttpServiceTlsMisconfigurationTest {
|
||||
|
||||
protected static final Vertx vertx = Vertx.vertx();
|
||||
|
||||
private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
private static final String CLIENT_VERSION = "0.1.0";
|
||||
private static final String CLIENT_COMMIT = "12345678";
|
||||
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
private static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
|
||||
private static final NatService natService = new NatService(Optional.empty());
|
||||
private final SelfSignedP12Certificate besuCertificate = SelfSignedP12Certificate.create();
|
||||
@@ -104,9 +102,7 @@ class JsonRpcHttpServiceTlsMisconfigurationTest {
|
||||
rpcMethods =
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
CHAIN_ID,
|
||||
new StubGenesisConfigOptions(),
|
||||
peerDiscoveryMock,
|
||||
|
||||
@@ -81,9 +81,7 @@ public class JsonRpcHttpServiceTlsTest {
|
||||
protected static final Vertx vertx = Vertx.vertx();
|
||||
|
||||
private static final String JSON_HEADER = "application/json; charset=utf-8";
|
||||
private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
private static final String CLIENT_VERSION = "0.1.0";
|
||||
private static final String CLIENT_COMMIT = "12345678";
|
||||
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
private static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
|
||||
private static final NatService natService = new NatService(Optional.empty());
|
||||
private JsonRpcHttpService service;
|
||||
@@ -105,9 +103,7 @@ public class JsonRpcHttpServiceTlsTest {
|
||||
rpcMethods =
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
CHAIN_ID,
|
||||
new StubGenesisConfigOptions(),
|
||||
peerDiscoveryMock,
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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.jsonrpc.internal.methods.engine;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
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.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1;
|
||||
|
||||
import io.vertx.core.Vertx;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
class EngineGetClientVersionV1Test {
|
||||
|
||||
private static final String ENGINE_CLIENT_CODE = "BU";
|
||||
private static final String ENGINE_CLIENT_NAME = "Besu";
|
||||
|
||||
private static final String CLIENT_VERSION = "v25.6.7-dev-abcdef12";
|
||||
private static final String COMMIT = "abcdef12";
|
||||
|
||||
private EngineGetClientVersionV1 getClientVersion;
|
||||
|
||||
@BeforeEach
|
||||
void before() {
|
||||
getClientVersion =
|
||||
new EngineGetClientVersionV1(
|
||||
Mockito.mock(Vertx.class),
|
||||
Mockito.mock(ProtocolContext.class),
|
||||
Mockito.mock(EngineCallListener.class),
|
||||
CLIENT_VERSION,
|
||||
COMMIT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetName() {
|
||||
assertThat(getClientVersion.getName()).isEqualTo("engine_getClientVersionV1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSyncResponse() {
|
||||
JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("v", "m", null));
|
||||
JsonRpcResponse actualResult = getClientVersion.syncResponse(request);
|
||||
|
||||
assertThat(actualResult).isInstanceOf(JsonRpcSuccessResponse.class);
|
||||
JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) actualResult;
|
||||
assertThat(successResponse.getResult()).isInstanceOf(EngineGetClientVersionResultV1.class);
|
||||
EngineGetClientVersionResultV1 actualEngineGetClientVersionResultV1 =
|
||||
(EngineGetClientVersionResultV1) successResponse.getResult();
|
||||
assertThat(actualEngineGetClientVersionResultV1.getName()).isEqualTo(ENGINE_CLIENT_NAME);
|
||||
assertThat(actualEngineGetClientVersionResultV1.getCode()).isEqualTo(ENGINE_CLIENT_CODE);
|
||||
assertThat(actualEngineGetClientVersionResultV1.getVersion()).isEqualTo(CLIENT_VERSION);
|
||||
assertThat(actualEngineGetClientVersionResultV1.getCommit()).isEqualTo(COMMIT);
|
||||
}
|
||||
}
|
||||
@@ -115,9 +115,7 @@ public class WebSocketServiceLoginTest {
|
||||
protected static OkHttpClient client;
|
||||
protected static String baseUrl;
|
||||
protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
|
||||
protected static final String CLIENT_VERSION = "0.1.0";
|
||||
protected static final String CLIENT_COMMIT = "12345678";
|
||||
protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
|
||||
protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
|
||||
protected static P2PNetwork peerDiscoveryMock;
|
||||
protected static BlockchainQueries blockchainQueries;
|
||||
@@ -169,9 +167,7 @@ public class WebSocketServiceLoginTest {
|
||||
spy(
|
||||
new JsonRpcMethodsFactory()
|
||||
.methods(
|
||||
CLIENT_NODE_NAME,
|
||||
CLIENT_VERSION,
|
||||
CLIENT_COMMIT,
|
||||
CHAIN_ID,
|
||||
genesisConfigOptions,
|
||||
peerDiscoveryMock,
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory;
|
||||
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory;
|
||||
@@ -120,7 +121,8 @@ public class WorldStateDownloaderBenchmark {
|
||||
syncConfig.getWorldStateMaxRequestsWithoutProgress(),
|
||||
syncConfig.getWorldStateMinMillisBeforeStalling(),
|
||||
Clock.fixed(Instant.ofEpochSecond(1000), ZoneOffset.UTC),
|
||||
metricsSystem);
|
||||
metricsSystem,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
private Hash createExistingWorldState() {
|
||||
|
||||
@@ -291,12 +291,13 @@ public class EthPeer implements Comparable<EthPeer> {
|
||||
if (messageData.getSize() > maxMessageSize) {
|
||||
// This is a bug or else a misconfiguration of the max message size.
|
||||
LOG.error(
|
||||
"Sending {} message to peer ({}) which exceeds local message size limit of {} bytes. Message code: {}, Message Size: {}",
|
||||
"Dropping {} message to peer ({}) which exceeds local message size limit of {} bytes. Message code: {}, Message Size: {}",
|
||||
protocolName,
|
||||
this,
|
||||
maxMessageSize,
|
||||
messageData.getCode(),
|
||||
messageData.getSize());
|
||||
return null;
|
||||
}
|
||||
|
||||
if (requestManagers.containsKey(protocolName)) {
|
||||
|
||||
@@ -107,7 +107,8 @@ public class EthProtocolManager implements ProtocolManager, MinedBlockObserver {
|
||||
this.ethMessages = ethMessages;
|
||||
this.ethContext = ethContext;
|
||||
|
||||
this.blockBroadcaster = new BlockBroadcaster(ethContext);
|
||||
this.blockBroadcaster =
|
||||
new BlockBroadcaster(ethContext, ethereumWireProtocolConfiguration.getMaxMessageSize());
|
||||
|
||||
this.supportedCapabilities =
|
||||
calculateCapabilities(synchronizerConfiguration, ethereumWireProtocolConfiguration);
|
||||
|
||||
@@ -44,11 +44,20 @@ public class NewBlockMessage extends AbstractMessageData {
|
||||
return MESSAGE_CODE;
|
||||
}
|
||||
|
||||
public static NewBlockMessage create(final Block block, final Difficulty totalDifficulty) {
|
||||
public static NewBlockMessage create(
|
||||
final Block block, final Difficulty totalDifficulty, final int maxMessageSize)
|
||||
throws IllegalArgumentException {
|
||||
final NewBlockMessageData msgData = new NewBlockMessageData(block, totalDifficulty);
|
||||
final BytesValueRLPOutput out = new BytesValueRLPOutput();
|
||||
msgData.writeTo(out);
|
||||
return new NewBlockMessage(out.encoded());
|
||||
final Bytes data = out.encoded();
|
||||
if (data.size() > maxMessageSize) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"Block message size %d bytes is larger than allowed message size %d bytes",
|
||||
data.size(), maxMessageSize));
|
||||
}
|
||||
return new NewBlockMessage(data);
|
||||
}
|
||||
|
||||
public static NewBlockMessage readFrom(final MessageData message) {
|
||||
|
||||
@@ -28,11 +28,13 @@ public class BlockBroadcaster {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BlockBroadcaster.class);
|
||||
|
||||
private final EthContext ethContext;
|
||||
private final int maxMessageSize;
|
||||
private final Subscribers<BlockPropagatedSubscriber> blockPropagatedSubscribers =
|
||||
Subscribers.create();
|
||||
|
||||
public BlockBroadcaster(final EthContext ethContext) {
|
||||
public BlockBroadcaster(final EthContext ethContext, final int maxMessageSize) {
|
||||
this.ethContext = ethContext;
|
||||
this.maxMessageSize = maxMessageSize;
|
||||
}
|
||||
|
||||
public long subscribePropagateNewBlocks(final BlockPropagatedSubscriber callback) {
|
||||
@@ -45,7 +47,13 @@ public class BlockBroadcaster {
|
||||
|
||||
public void propagate(final Block block, final Difficulty totalDifficulty) {
|
||||
blockPropagatedSubscribers.forEach(listener -> listener.accept(block, totalDifficulty));
|
||||
final NewBlockMessage newBlockMessage = NewBlockMessage.create(block, totalDifficulty);
|
||||
final NewBlockMessage newBlockMessage;
|
||||
try {
|
||||
newBlockMessage = NewBlockMessage.create(block, totalDifficulty, this.maxMessageSize);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
LOG.error("Failed to create block", e);
|
||||
return;
|
||||
}
|
||||
ethContext
|
||||
.getEthPeers()
|
||||
.streamAvailablePeers()
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.storage.StorageProvider;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.data.SyncStatus;
|
||||
import org.hyperledger.besu.plugin.services.BesuEvents;
|
||||
import org.hyperledger.besu.plugin.services.BesuEvents.SyncStatusListener;
|
||||
@@ -67,6 +68,7 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
private final Optional<BlockPropagationManager> blockPropagationManager;
|
||||
private final Supplier<Optional<FastSyncDownloader<?>>> fastSyncFactory;
|
||||
private final SyncDurationMetrics syncDurationMetrics;
|
||||
private Optional<FastSyncDownloader<?>> fastSyncDownloader;
|
||||
private final Optional<FullSyncDownloader> fullSyncDownloader;
|
||||
private final ProtocolContext protocolContext;
|
||||
@@ -118,6 +120,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi
|
||||
metricsSystem,
|
||||
blockBroadcaster));
|
||||
|
||||
syncDurationMetrics = new SyncDurationMetrics(metricsSystem);
|
||||
|
||||
this.fullSyncDownloader =
|
||||
terminationCondition.shouldStopDownload()
|
||||
? Optional.empty()
|
||||
@@ -129,7 +133,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi
|
||||
ethContext,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
terminationCondition));
|
||||
terminationCondition,
|
||||
syncDurationMetrics));
|
||||
|
||||
if (SyncMode.FAST.equals(syncConfig.getSyncMode())) {
|
||||
this.fastSyncFactory =
|
||||
@@ -144,7 +149,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi
|
||||
ethContext,
|
||||
worldStateStorageCoordinator,
|
||||
syncState,
|
||||
clock);
|
||||
clock,
|
||||
syncDurationMetrics);
|
||||
} else if (syncConfig.getSyncMode() == SyncMode.CHECKPOINT) {
|
||||
this.fastSyncFactory =
|
||||
() ->
|
||||
@@ -159,7 +165,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi
|
||||
ethContext,
|
||||
worldStateStorageCoordinator,
|
||||
syncState,
|
||||
clock);
|
||||
clock,
|
||||
syncDurationMetrics);
|
||||
} else {
|
||||
this.fastSyncFactory =
|
||||
() ->
|
||||
@@ -174,7 +181,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi
|
||||
ethContext,
|
||||
worldStateStorageCoordinator,
|
||||
syncState,
|
||||
clock);
|
||||
clock,
|
||||
syncDurationMetrics);
|
||||
}
|
||||
|
||||
// create a non-resync fast sync downloader:
|
||||
@@ -205,6 +213,9 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi
|
||||
public CompletableFuture<Void> start() {
|
||||
if (running.compareAndSet(false, true)) {
|
||||
LOG.info("Starting synchronizer.");
|
||||
|
||||
syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.TOTAL_SYNC_DURATION);
|
||||
|
||||
blockPropagationManager.ifPresent(
|
||||
manager -> {
|
||||
if (!manager.isRunning()) {
|
||||
@@ -390,6 +401,10 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi
|
||||
blockPropagationManager.ifPresent(BlockPropagationManager::stop);
|
||||
LOG.info("Stopping the pruner.");
|
||||
running.set(false);
|
||||
|
||||
syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.FLAT_DB_HEAL);
|
||||
syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.TOTAL_SYNC_DURATION);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncTarget;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.tasks.exceptions.InvalidBlockException;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
||||
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
|
||||
@@ -51,6 +52,7 @@ public class PipelineChainDownloader implements ChainDownloader {
|
||||
private final AtomicBoolean cancelled = new AtomicBoolean(false);
|
||||
private final Counter pipelineCompleteCounter;
|
||||
private final Counter pipelineErrorCounter;
|
||||
private final SyncDurationMetrics syncDurationMetrics;
|
||||
private Pipeline<?> currentDownloadPipeline;
|
||||
|
||||
public PipelineChainDownloader(
|
||||
@@ -58,11 +60,13 @@ public class PipelineChainDownloader implements ChainDownloader {
|
||||
final AbstractSyncTargetManager syncTargetManager,
|
||||
final DownloadPipelineFactory downloadPipelineFactory,
|
||||
final EthScheduler scheduler,
|
||||
final MetricsSystem metricsSystem) {
|
||||
final MetricsSystem metricsSystem,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
this.syncState = syncState;
|
||||
this.syncTargetManager = syncTargetManager;
|
||||
this.downloadPipelineFactory = downloadPipelineFactory;
|
||||
this.scheduler = scheduler;
|
||||
this.syncDurationMetrics = syncDurationMetrics;
|
||||
|
||||
final LabelledMetric<Counter> labelledCounter =
|
||||
metricsSystem.createLabelledCounter(
|
||||
@@ -79,6 +83,9 @@ public class PipelineChainDownloader implements ChainDownloader {
|
||||
if (!started.compareAndSet(false, true)) {
|
||||
throw new IllegalStateException("Cannot start a chain download twice");
|
||||
}
|
||||
|
||||
syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.CHAIN_DOWNLOAD_DURATION);
|
||||
|
||||
return performDownload();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.trie.CompactEncoding;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues;
|
||||
|
||||
@@ -62,7 +63,8 @@ public class CheckpointDownloaderFactory extends SnapDownloaderFactory {
|
||||
final EthContext ethContext,
|
||||
final WorldStateStorageCoordinator worldStateStorageCoordinator,
|
||||
final SyncState syncState,
|
||||
final Clock clock) {
|
||||
final Clock clock,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
|
||||
final Path fastSyncDataDirectory = dataDirectory.resolve(FAST_SYNC_FOLDER);
|
||||
final FastSyncStateStorage fastSyncStateStorage =
|
||||
@@ -149,7 +151,8 @@ public class CheckpointDownloaderFactory extends SnapDownloaderFactory {
|
||||
syncConfig.getWorldStateMaxRequestsWithoutProgress(),
|
||||
syncConfig.getWorldStateMinMillisBeforeStalling(),
|
||||
clock,
|
||||
metricsSystem);
|
||||
metricsSystem,
|
||||
syncDurationMetrics);
|
||||
final FastSyncDownloader<SnapDataRequest> fastSyncDownloader =
|
||||
new SnapSyncDownloader(
|
||||
fastSyncActions,
|
||||
@@ -158,7 +161,8 @@ public class CheckpointDownloaderFactory extends SnapDownloaderFactory {
|
||||
fastSyncStateStorage,
|
||||
snapTaskCollection,
|
||||
fastSyncDataDirectory,
|
||||
snapSyncState);
|
||||
snapSyncState,
|
||||
syncDurationMetrics);
|
||||
syncState.setWorldStateDownloadStatus(snapWorldStateDownloader);
|
||||
return Optional.of(fastSyncDownloader);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
public class CheckpointSyncActions extends FastSyncActions {
|
||||
@@ -48,7 +49,8 @@ public class CheckpointSyncActions extends FastSyncActions {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChainDownloader createChainDownloader(final FastSyncState currentState) {
|
||||
public ChainDownloader createChainDownloader(
|
||||
final FastSyncState currentState, final SyncDurationMetrics syncDurationMetrics) {
|
||||
return CheckpointSyncChainDownloader.create(
|
||||
syncConfig,
|
||||
worldStateStorageCoordinator,
|
||||
@@ -57,6 +59,7 @@ public class CheckpointSyncActions extends FastSyncActions {
|
||||
ethContext,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
currentState);
|
||||
currentState,
|
||||
syncDurationMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.SyncTargetManager;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
public class CheckpointSyncChainDownloader extends FastSyncChainDownloader {
|
||||
@@ -37,7 +38,8 @@ public class CheckpointSyncChainDownloader extends FastSyncChainDownloader {
|
||||
final EthContext ethContext,
|
||||
final SyncState syncState,
|
||||
final MetricsSystem metricsSystem,
|
||||
final FastSyncState fastSyncState) {
|
||||
final FastSyncState fastSyncState,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
|
||||
final SyncTargetManager syncTargetManager =
|
||||
new SyncTargetManager(
|
||||
@@ -55,6 +57,7 @@ public class CheckpointSyncChainDownloader extends FastSyncChainDownloader {
|
||||
new CheckpointSyncDownloadPipelineFactory(
|
||||
config, protocolSchedule, protocolContext, ethContext, fastSyncState, metricsSystem),
|
||||
ethContext.getScheduler(),
|
||||
metricsSystem);
|
||||
metricsSystem,
|
||||
syncDurationMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByH
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
||||
|
||||
@@ -155,7 +156,8 @@ public class FastSyncActions {
|
||||
return fastSyncState;
|
||||
}
|
||||
|
||||
public ChainDownloader createChainDownloader(final FastSyncState currentState) {
|
||||
public ChainDownloader createChainDownloader(
|
||||
final FastSyncState currentState, final SyncDurationMetrics syncDurationMetrics) {
|
||||
return FastSyncChainDownloader.create(
|
||||
syncConfig,
|
||||
worldStateStorageCoordinator,
|
||||
@@ -164,7 +166,8 @@ public class FastSyncActions {
|
||||
ethContext,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
currentState);
|
||||
currentState,
|
||||
syncDurationMetrics);
|
||||
}
|
||||
|
||||
private CompletableFuture<FastSyncState> downloadPivotBlockHeader(final Hash hash) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
public class FastSyncChainDownloader {
|
||||
@@ -36,7 +37,8 @@ public class FastSyncChainDownloader {
|
||||
final EthContext ethContext,
|
||||
final SyncState syncState,
|
||||
final MetricsSystem metricsSystem,
|
||||
final FastSyncState fastSyncState) {
|
||||
final FastSyncState fastSyncState,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
|
||||
final SyncTargetManager syncTargetManager =
|
||||
new SyncTargetManager(
|
||||
@@ -53,6 +55,7 @@ public class FastSyncChainDownloader {
|
||||
new FastSyncDownloadPipelineFactory(
|
||||
config, protocolSchedule, protocolContext, ethContext, fastSyncState, metricsSystem),
|
||||
ethContext.getScheduler(),
|
||||
metricsSystem);
|
||||
metricsSystem,
|
||||
syncDurationMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.eth.sync.worldstate.StalledDownloadExceptio
|
||||
import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
import org.hyperledger.besu.services.tasks.TaskCollection;
|
||||
import org.hyperledger.besu.util.ExceptionUtils;
|
||||
@@ -52,6 +53,7 @@ public class FastSyncDownloader<REQUEST> {
|
||||
private final WorldStateDownloader worldStateDownloader;
|
||||
private final TaskCollection<REQUEST> taskCollection;
|
||||
private final Path fastSyncDataDirectory;
|
||||
private final SyncDurationMetrics syncDurationMetrics;
|
||||
private volatile Optional<TrailingPeerRequirements> trailingPeerRequirements = Optional.empty();
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
|
||||
@@ -66,7 +68,8 @@ public class FastSyncDownloader<REQUEST> {
|
||||
final FastSyncStateStorage fastSyncStateStorage,
|
||||
final TaskCollection<REQUEST> taskCollection,
|
||||
final Path fastSyncDataDirectory,
|
||||
final FastSyncState initialFastSyncState) {
|
||||
final FastSyncState initialFastSyncState,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
this.fastSyncActions = fastSyncActions;
|
||||
this.worldStateStorageCoordinator = worldStateStorageCoordinator;
|
||||
this.worldStateDownloader = worldStateDownloader;
|
||||
@@ -74,6 +77,7 @@ public class FastSyncDownloader<REQUEST> {
|
||||
this.taskCollection = taskCollection;
|
||||
this.fastSyncDataDirectory = fastSyncDataDirectory;
|
||||
this.initialFastSyncState = initialFastSyncState;
|
||||
this.syncDurationMetrics = syncDurationMetrics;
|
||||
}
|
||||
|
||||
public CompletableFuture<FastSyncState> start() {
|
||||
@@ -81,6 +85,7 @@ public class FastSyncDownloader<REQUEST> {
|
||||
throw new IllegalStateException("SyncDownloader already running");
|
||||
}
|
||||
LOG.info("Starting pivot-based sync");
|
||||
|
||||
return start(initialFastSyncState);
|
||||
}
|
||||
|
||||
@@ -189,7 +194,8 @@ public class FastSyncDownloader<REQUEST> {
|
||||
}
|
||||
final CompletableFuture<Void> worldStateFuture =
|
||||
worldStateDownloader.run(fastSyncActions, currentState);
|
||||
final ChainDownloader chainDownloader = fastSyncActions.createChainDownloader(currentState);
|
||||
final ChainDownloader chainDownloader =
|
||||
fastSyncActions.createChainDownloader(currentState, syncDurationMetrics);
|
||||
final CompletableFuture<Void> chainFuture = chainDownloader.start();
|
||||
|
||||
// If either download fails, cancel the other one.
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues;
|
||||
|
||||
@@ -60,7 +61,8 @@ public class FastDownloaderFactory {
|
||||
final EthContext ethContext,
|
||||
final WorldStateStorageCoordinator worldStateStorageCoordinator,
|
||||
final SyncState syncState,
|
||||
final Clock clock) {
|
||||
final Clock clock,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
|
||||
final Path fastSyncDataDirectory = dataDirectory.resolve(FAST_SYNC_FOLDER);
|
||||
final FastSyncStateStorage fastSyncStateStorage =
|
||||
@@ -114,7 +116,8 @@ public class FastDownloaderFactory {
|
||||
syncConfig.getWorldStateMaxRequestsWithoutProgress(),
|
||||
syncConfig.getWorldStateMinMillisBeforeStalling(),
|
||||
clock,
|
||||
metricsSystem);
|
||||
metricsSystem,
|
||||
syncDurationMetrics);
|
||||
final FastSyncDownloader<NodeDataRequest> fastSyncDownloader =
|
||||
new FastSyncDownloader<>(
|
||||
new FastSyncActions(
|
||||
@@ -131,7 +134,8 @@ public class FastDownloaderFactory {
|
||||
fastSyncStateStorage,
|
||||
taskCollection,
|
||||
fastSyncDataDirectory,
|
||||
fastSyncState);
|
||||
fastSyncState,
|
||||
syncDurationMetrics);
|
||||
syncState.setWorldStateDownloadStatus(worldStateDownloader);
|
||||
return Optional.of(fastSyncDownloader);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldDownloadState;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues;
|
||||
|
||||
import java.time.Clock;
|
||||
@@ -37,13 +38,15 @@ public class FastWorldDownloadState extends WorldDownloadState<NodeDataRequest>
|
||||
final InMemoryTasksPriorityQueues<NodeDataRequest> pendingRequests,
|
||||
final int maxRequestsWithoutProgress,
|
||||
final long minMillisBeforeStalling,
|
||||
final Clock clock) {
|
||||
final Clock clock,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
super(
|
||||
worldStateStorageCoordinator,
|
||||
pendingRequests,
|
||||
maxRequestsWithoutProgress,
|
||||
minMillisBeforeStalling,
|
||||
clock);
|
||||
clock,
|
||||
syncDurationMetrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,7 +73,9 @@ public class FastWorldDownloadState extends WorldDownloadState<NodeDataRequest>
|
||||
// THere are no more inputs to process so make sure we wake up any threads waiting to dequeue
|
||||
// so they can give up waiting.
|
||||
notifyAll();
|
||||
|
||||
LOG.info("Finished downloading world state from peers");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues;
|
||||
|
||||
@@ -51,6 +52,7 @@ public class FastWorldStateDownloader implements WorldStateDownloader {
|
||||
private final WorldStateStorageCoordinator worldStateStorageCoordinator;
|
||||
|
||||
private final AtomicReference<FastWorldDownloadState> downloadState = new AtomicReference<>();
|
||||
private final SyncDurationMetrics syncDurationMetrics;
|
||||
|
||||
private Optional<CompleteTaskStep> maybeCompleteTask = Optional.empty();
|
||||
|
||||
@@ -63,7 +65,8 @@ public class FastWorldStateDownloader implements WorldStateDownloader {
|
||||
final int maxNodeRequestsWithoutProgress,
|
||||
final long minMillisBeforeStalling,
|
||||
final Clock clock,
|
||||
final MetricsSystem metricsSystem) {
|
||||
final MetricsSystem metricsSystem,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
this.ethContext = ethContext;
|
||||
this.worldStateStorageCoordinator = worldStateStorageCoordinator;
|
||||
this.taskCollection = taskCollection;
|
||||
@@ -73,6 +76,7 @@ public class FastWorldStateDownloader implements WorldStateDownloader {
|
||||
this.minMillisBeforeStalling = minMillisBeforeStalling;
|
||||
this.clock = clock;
|
||||
this.metricsSystem = metricsSystem;
|
||||
this.syncDurationMetrics = syncDurationMetrics;
|
||||
|
||||
metricsSystem.createIntegerGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
@@ -137,7 +141,8 @@ public class FastWorldStateDownloader implements WorldStateDownloader {
|
||||
taskCollection,
|
||||
maxNodeRequestsWithoutProgress,
|
||||
minMillisBeforeStalling,
|
||||
clock);
|
||||
clock,
|
||||
syncDurationMetrics);
|
||||
this.downloadState.set(newDownloadState);
|
||||
|
||||
if (!newDownloadState.downloadWasResumed()) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.eth.sync.PipelineChainDownloader;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
public class FullSyncChainDownloader {
|
||||
@@ -33,7 +34,8 @@ public class FullSyncChainDownloader {
|
||||
final EthContext ethContext,
|
||||
final SyncState syncState,
|
||||
final MetricsSystem metricsSystem,
|
||||
final SyncTerminationCondition terminationCondition) {
|
||||
final SyncTerminationCondition terminationCondition,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
|
||||
final FullSyncTargetManager syncTargetManager =
|
||||
new FullSyncTargetManager(
|
||||
@@ -55,6 +57,7 @@ public class FullSyncChainDownloader {
|
||||
metricsSystem,
|
||||
terminationCondition),
|
||||
ethContext.getScheduler(),
|
||||
metricsSystem);
|
||||
metricsSystem,
|
||||
syncDurationMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -43,7 +44,8 @@ public class FullSyncDownloader {
|
||||
final EthContext ethContext,
|
||||
final SyncState syncState,
|
||||
final MetricsSystem metricsSystem,
|
||||
final SyncTerminationCondition terminationCondition) {
|
||||
final SyncTerminationCondition terminationCondition,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
this.syncConfig = syncConfig;
|
||||
this.protocolContext = protocolContext;
|
||||
this.syncState = syncState;
|
||||
@@ -56,7 +58,8 @@ public class FullSyncDownloader {
|
||||
ethContext,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
terminationCondition);
|
||||
terminationCondition,
|
||||
syncDurationMetrics);
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> start() {
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.trie.CompactEncoding;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues;
|
||||
|
||||
@@ -58,7 +59,8 @@ public class SnapDownloaderFactory extends FastDownloaderFactory {
|
||||
final EthContext ethContext,
|
||||
final WorldStateStorageCoordinator worldStateStorageCoordinator,
|
||||
final SyncState syncState,
|
||||
final Clock clock) {
|
||||
final Clock clock,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
|
||||
final Path fastSyncDataDirectory = dataDirectory.resolve(FAST_SYNC_FOLDER);
|
||||
final FastSyncStateStorage fastSyncStateStorage =
|
||||
@@ -93,10 +95,7 @@ public class SnapDownloaderFactory extends FastDownloaderFactory {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
final SnapSyncProcessState snapSyncState =
|
||||
new SnapSyncProcessState(
|
||||
fastSyncStateStorage.loadState(
|
||||
ScheduleBasedBlockHeaderFunctions.create(protocolSchedule)));
|
||||
final SnapSyncProcessState snapSyncState = new SnapSyncProcessState(fastSyncState);
|
||||
|
||||
final InMemoryTasksPriorityQueues<SnapDataRequest> snapTaskCollection =
|
||||
createSnapWorldStateDownloaderTaskCollection();
|
||||
@@ -112,7 +111,8 @@ public class SnapDownloaderFactory extends FastDownloaderFactory {
|
||||
syncConfig.getWorldStateMaxRequestsWithoutProgress(),
|
||||
syncConfig.getWorldStateMinMillisBeforeStalling(),
|
||||
clock,
|
||||
metricsSystem);
|
||||
metricsSystem,
|
||||
syncDurationMetrics);
|
||||
final FastSyncDownloader<SnapDataRequest> fastSyncDownloader =
|
||||
new SnapSyncDownloader(
|
||||
new FastSyncActions(
|
||||
@@ -129,7 +129,8 @@ public class SnapDownloaderFactory extends FastDownloaderFactory {
|
||||
fastSyncStateStorage,
|
||||
snapTaskCollection,
|
||||
fastSyncDataDirectory,
|
||||
snapSyncState);
|
||||
snapSyncState,
|
||||
syncDurationMetrics);
|
||||
syncState.setWorldStateDownloadStatus(snapWorldStateDownloader);
|
||||
return Optional.of(fastSyncDownloader);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncStateStorage;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.snapsync.request.SnapDataRequest;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.services.tasks.TaskCollection;
|
||||
|
||||
import java.nio.file.Path;
|
||||
@@ -35,7 +36,8 @@ public class SnapSyncDownloader extends FastSyncDownloader<SnapDataRequest> {
|
||||
final FastSyncStateStorage fastSyncStateStorage,
|
||||
final TaskCollection<SnapDataRequest> taskCollection,
|
||||
final Path fastSyncDataDirectory,
|
||||
final FastSyncState initialFastSyncState) {
|
||||
final FastSyncState initialFastSyncState,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
super(
|
||||
fastSyncActions,
|
||||
worldStateStorageCoordinator,
|
||||
@@ -43,7 +45,8 @@ public class SnapSyncDownloader extends FastSyncDownloader<SnapDataRequest> {
|
||||
fastSyncStateStorage,
|
||||
taskCollection,
|
||||
fastSyncDataDirectory,
|
||||
initialFastSyncState);
|
||||
initialFastSyncState,
|
||||
syncDurationMetrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -36,6 +36,8 @@ import org.hyperledger.besu.ethereum.worldstate.FlatDbMode;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTaskQueue;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues;
|
||||
@@ -92,6 +94,8 @@ public class SnapWorldDownloadState extends WorldDownloadState<SnapDataRequest>
|
||||
// metrics around the snapsync
|
||||
private final SnapSyncMetricsManager metricsManager;
|
||||
|
||||
private final AtomicBoolean trieHealStartedBefore = new AtomicBoolean(false);
|
||||
|
||||
public SnapWorldDownloadState(
|
||||
final WorldStateStorageCoordinator worldStateStorageCoordinator,
|
||||
final SnapSyncStatePersistenceManager snapContext,
|
||||
@@ -102,13 +106,15 @@ public class SnapWorldDownloadState extends WorldDownloadState<SnapDataRequest>
|
||||
final long minMillisBeforeStalling,
|
||||
final SnapSyncMetricsManager metricsManager,
|
||||
final Clock clock,
|
||||
final EthContext ethContext) {
|
||||
final EthContext ethContext,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
super(
|
||||
worldStateStorageCoordinator,
|
||||
pendingRequests,
|
||||
maxRequestsWithoutProgress,
|
||||
minMillisBeforeStalling,
|
||||
clock);
|
||||
clock,
|
||||
syncDurationMetrics);
|
||||
this.snapContext = snapContext;
|
||||
this.blockchain = blockchain;
|
||||
this.snapSyncState = snapSyncState;
|
||||
@@ -116,46 +122,34 @@ public class SnapWorldDownloadState extends WorldDownloadState<SnapDataRequest>
|
||||
this.blockObserverId = blockchain.observeBlockAdded(createBlockchainObserver());
|
||||
this.ethContext = ethContext;
|
||||
|
||||
metricsManager
|
||||
.getMetricsSystem()
|
||||
.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_account_requests_current",
|
||||
"Number of account pending requests for snap sync world state download",
|
||||
pendingAccountRequests::size);
|
||||
metricsManager
|
||||
.getMetricsSystem()
|
||||
.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_storage_requests_current",
|
||||
"Number of storage pending requests for snap sync world state download",
|
||||
pendingStorageRequests::size);
|
||||
metricsManager
|
||||
.getMetricsSystem()
|
||||
.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_big_storage_requests_current",
|
||||
"Number of storage pending requests for snap sync world state download",
|
||||
pendingLargeStorageRequests::size);
|
||||
metricsManager
|
||||
.getMetricsSystem()
|
||||
.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_code_requests_current",
|
||||
"Number of code pending requests for snap sync world state download",
|
||||
pendingCodeRequests::size);
|
||||
metricsManager
|
||||
.getMetricsSystem()
|
||||
.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_trie_node_requests_current",
|
||||
"Number of trie node pending requests for snap sync world state download",
|
||||
pendingTrieNodeRequests::size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void notifyTaskAvailable() {
|
||||
notifyAll();
|
||||
final MetricsSystem metricsSystem = metricsManager.getMetricsSystem();
|
||||
metricsSystem.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_account_requests_current",
|
||||
"Number of account pending requests for snap sync world state download",
|
||||
pendingAccountRequests::size);
|
||||
metricsSystem.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_storage_requests_current",
|
||||
"Number of storage pending requests for snap sync world state download",
|
||||
pendingStorageRequests::size);
|
||||
metricsSystem.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_big_storage_requests_current",
|
||||
"Number of storage pending requests for snap sync world state download",
|
||||
pendingLargeStorageRequests::size);
|
||||
metricsSystem.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_code_requests_current",
|
||||
"Number of code pending requests for snap sync world state download",
|
||||
pendingCodeRequests::size);
|
||||
metricsSystem.createLongGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
"snap_world_state_pending_trie_node_requests_current",
|
||||
"Number of trie node pending requests for snap sync world state download",
|
||||
pendingTrieNodeRequests::size);
|
||||
syncDurationMetrics.startTimer(
|
||||
SyncDurationMetrics.Labels.SNAP_INITIAL_WORLD_STATE_DOWNLOAD_DURATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,6 +185,9 @@ public class SnapWorldDownloadState extends WorldDownloadState<SnapDataRequest>
|
||||
// if all snapsync tasks are completed and the healing was running and the blockchain is not
|
||||
// behind the pivot block
|
||||
else {
|
||||
syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.SNAP_WORLD_STATE_HEALING_DURATION);
|
||||
syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.CHAIN_DOWNLOAD_DURATION);
|
||||
|
||||
// If the flat database healing process is not in progress and the flat database mode is
|
||||
// FULL
|
||||
if (!snapSyncState.isHealFlatDatabaseInProgress()
|
||||
@@ -217,6 +214,7 @@ public class SnapWorldDownloadState extends WorldDownloadState<SnapDataRequest>
|
||||
// Clear the snap context
|
||||
snapContext.clear();
|
||||
internalFuture.complete(null);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -236,6 +234,12 @@ public class SnapWorldDownloadState extends WorldDownloadState<SnapDataRequest>
|
||||
|
||||
/** Method to start the healing process of the trie */
|
||||
public synchronized void startTrieHeal() {
|
||||
if (trieHealStartedBefore.compareAndSet(false, true)) {
|
||||
syncDurationMetrics.stopTimer(
|
||||
SyncDurationMetrics.Labels.SNAP_INITIAL_WORLD_STATE_DOWNLOAD_DURATION);
|
||||
|
||||
syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.SNAP_WORLD_STATE_HEALING_DURATION);
|
||||
}
|
||||
snapContext.clearAccountRangeTasks();
|
||||
snapSyncState.setHealTrieStatus(true);
|
||||
// Try to find a new pivot block before starting the healing process
|
||||
@@ -272,6 +276,7 @@ public class SnapWorldDownloadState extends WorldDownloadState<SnapDataRequest>
|
||||
|
||||
public synchronized void startFlatDatabaseHeal(final BlockHeader header) {
|
||||
LOG.info("Initiating the healing process for the flat database");
|
||||
syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.FLAT_DB_HEAL);
|
||||
snapSyncState.setHealFlatDatabaseInProgress(true);
|
||||
final Map<Bytes32, Bytes32> ranges = RangeManager.generateAllRanges(16);
|
||||
ranges.forEach(
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.trie.RangeManager;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues;
|
||||
@@ -67,6 +68,7 @@ public class SnapWorldStateDownloader implements WorldStateDownloader {
|
||||
private final WorldStateStorageCoordinator worldStateStorageCoordinator;
|
||||
|
||||
private final AtomicReference<SnapWorldDownloadState> downloadState = new AtomicReference<>();
|
||||
private final SyncDurationMetrics syncDurationMetrics;
|
||||
|
||||
public SnapWorldStateDownloader(
|
||||
final EthContext ethContext,
|
||||
@@ -79,7 +81,8 @@ public class SnapWorldStateDownloader implements WorldStateDownloader {
|
||||
final int maxNodeRequestsWithoutProgress,
|
||||
final long minMillisBeforeStalling,
|
||||
final Clock clock,
|
||||
final MetricsSystem metricsSystem) {
|
||||
final MetricsSystem metricsSystem,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
this.ethContext = ethContext;
|
||||
this.protocolContext = protocolContext;
|
||||
this.worldStateStorageCoordinator = worldStateStorageCoordinator;
|
||||
@@ -91,6 +94,7 @@ public class SnapWorldStateDownloader implements WorldStateDownloader {
|
||||
this.minMillisBeforeStalling = minMillisBeforeStalling;
|
||||
this.clock = clock;
|
||||
this.metricsSystem = metricsSystem;
|
||||
this.syncDurationMetrics = syncDurationMetrics;
|
||||
|
||||
metricsSystem.createIntegerGauge(
|
||||
BesuMetricCategory.SYNCHRONIZER,
|
||||
@@ -148,7 +152,8 @@ public class SnapWorldStateDownloader implements WorldStateDownloader {
|
||||
minMillisBeforeStalling,
|
||||
snapsyncMetricsManager,
|
||||
clock,
|
||||
ethContext);
|
||||
ethContext,
|
||||
syncDurationMetrics);
|
||||
|
||||
final Map<Bytes32, Bytes32> ranges = RangeManager.generateAllRanges(16);
|
||||
snapsyncMetricsManager.initRange(ranges);
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.task.EthTask;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues;
|
||||
import org.hyperledger.besu.services.tasks.Task;
|
||||
import org.hyperledger.besu.services.tasks.TasksPriorityProvider;
|
||||
@@ -37,6 +38,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class WorldDownloadState<REQUEST extends TasksPriorityProvider> {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WorldDownloadState.class);
|
||||
protected final SyncDurationMetrics syncDurationMetrics;
|
||||
|
||||
private boolean downloadWasResumed;
|
||||
protected final InMemoryTasksPriorityQueues<REQUEST> pendingRequests;
|
||||
@@ -61,7 +63,8 @@ public abstract class WorldDownloadState<REQUEST extends TasksPriorityProvider>
|
||||
final InMemoryTasksPriorityQueues<REQUEST> pendingRequests,
|
||||
final int maxRequestsWithoutProgress,
|
||||
final long minMillisBeforeStalling,
|
||||
final Clock clock) {
|
||||
final Clock clock,
|
||||
final SyncDurationMetrics syncDurationMetrics) {
|
||||
this.worldStateStorageCoordinator = worldStateStorageCoordinator;
|
||||
this.minMillisBeforeStalling = minMillisBeforeStalling;
|
||||
this.timestampOfLastProgress = clock.millis();
|
||||
@@ -69,6 +72,7 @@ public abstract class WorldDownloadState<REQUEST extends TasksPriorityProvider>
|
||||
this.pendingRequests = pendingRequests;
|
||||
this.maxRequestsWithoutProgress = maxRequestsWithoutProgress;
|
||||
this.clock = clock;
|
||||
this.syncDurationMetrics = syncDurationMetrics;
|
||||
this.internalFuture = new CompletableFuture<>();
|
||||
this.downloadFuture = new CompletableFuture<>();
|
||||
this.internalFuture.whenComplete(this::cleanup);
|
||||
|
||||
@@ -24,12 +24,14 @@ import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.RawMessage;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||||
import org.hyperledger.besu.util.number.ByteUnits;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class NewBlockMessageTest {
|
||||
private static final ProtocolSchedule protocolSchedule = ProtocolScheduleFixture.MAINNET;
|
||||
private static final int maxMessageSize = 10 * ByteUnits.MEGABYTE;
|
||||
|
||||
@Test
|
||||
public void roundTripNewBlockMessage() {
|
||||
@@ -37,7 +39,8 @@ public class NewBlockMessageTest {
|
||||
final BlockDataGenerator blockGenerator = new BlockDataGenerator();
|
||||
final Block blockForInsertion = blockGenerator.block();
|
||||
|
||||
final NewBlockMessage msg = NewBlockMessage.create(blockForInsertion, totalDifficulty);
|
||||
final NewBlockMessage msg =
|
||||
NewBlockMessage.create(blockForInsertion, totalDifficulty, maxMessageSize);
|
||||
assertThat(msg.getCode()).isEqualTo(EthPV62.NEW_BLOCK);
|
||||
assertThat(msg.totalDifficulty(protocolSchedule)).isEqualTo(totalDifficulty);
|
||||
final Block extractedBlock = msg.block(protocolSchedule);
|
||||
@@ -73,4 +76,14 @@ public class NewBlockMessageTest {
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> NewBlockMessage.readFrom(rawMsg));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createBlockMessageLargerThanLimitThrows() {
|
||||
final Difficulty totalDifficulty = Difficulty.of(98765);
|
||||
final BlockDataGenerator blockGenerator = new BlockDataGenerator();
|
||||
final Block newBlock = blockGenerator.block();
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> NewBlockMessage.create(newBlock, totalDifficulty, 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
import org.hyperledger.besu.testutil.TestClock;
|
||||
import org.hyperledger.besu.util.number.ByteUnits;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -95,6 +96,7 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
protected SyncState syncState;
|
||||
protected final MetricsSystem metricsSystem = new NoOpMetricsSystem();
|
||||
private final Hash finalizedHash = Hash.fromHexStringLenient("0x1337");
|
||||
private final int maxMessageSize = 10 * ByteUnits.MEGABYTE;
|
||||
|
||||
protected void setup(final DataStorageFormat dataStorageFormat) {
|
||||
blockchainUtil = BlockchainSetupUtil.forTesting(dataStorageFormat);
|
||||
@@ -222,11 +224,14 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0);
|
||||
final NewBlockMessage nextAnnouncement =
|
||||
NewBlockMessage.create(
|
||||
nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get());
|
||||
nextBlock,
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(),
|
||||
maxMessageSize);
|
||||
final NewBlockMessage nextNextAnnouncement =
|
||||
NewBlockMessage.create(
|
||||
nextNextBlock,
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextNextBlock.getHash()).get());
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextNextBlock.getHash()).get(),
|
||||
maxMessageSize);
|
||||
final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain());
|
||||
|
||||
// Broadcast first message
|
||||
@@ -256,11 +261,14 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0);
|
||||
final NewBlockMessage nextAnnouncement =
|
||||
NewBlockMessage.create(
|
||||
nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get());
|
||||
nextBlock,
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(),
|
||||
maxMessageSize);
|
||||
final NewBlockMessage nextNextAnnouncement =
|
||||
NewBlockMessage.create(
|
||||
nextNextBlock,
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextNextBlock.getHash()).get());
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextNextBlock.getHash()).get(),
|
||||
maxMessageSize);
|
||||
final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain());
|
||||
|
||||
// Broadcast second message first
|
||||
@@ -299,7 +307,9 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
block1.getHash(), block1.getHeader().getNumber())));
|
||||
final NewBlockMessage block2Msg =
|
||||
NewBlockMessage.create(
|
||||
block2, getFullBlockchain().getTotalDifficultyByHash(block2.getHash()).get());
|
||||
block2,
|
||||
getFullBlockchain().getTotalDifficultyByHash(block2.getHash()).get(),
|
||||
maxMessageSize);
|
||||
final NewBlockHashesMessage block3Msg =
|
||||
NewBlockHashesMessage.create(
|
||||
Collections.singletonList(
|
||||
@@ -307,7 +317,9 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
block3.getHash(), block3.getHeader().getNumber())));
|
||||
final NewBlockMessage block4Msg =
|
||||
NewBlockMessage.create(
|
||||
block4, getFullBlockchain().getTotalDifficultyByHash(block4.getHash()).get());
|
||||
block4,
|
||||
getFullBlockchain().getTotalDifficultyByHash(block4.getHash()).get(),
|
||||
maxMessageSize);
|
||||
final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain());
|
||||
|
||||
// Broadcast older blocks
|
||||
@@ -362,7 +374,9 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
nextBlock.getHash(), nextBlock.getHeader().getNumber())));
|
||||
final NewBlockMessage newBlock =
|
||||
NewBlockMessage.create(
|
||||
nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get());
|
||||
nextBlock,
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(),
|
||||
maxMessageSize);
|
||||
final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain());
|
||||
|
||||
// Broadcast first message
|
||||
@@ -413,7 +427,9 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
nextBlock.getHash(), nextBlock.getHeader().getNumber())));
|
||||
final NewBlockMessage newBlock =
|
||||
NewBlockMessage.create(
|
||||
nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get());
|
||||
nextBlock,
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(),
|
||||
maxMessageSize);
|
||||
|
||||
// Broadcast messages
|
||||
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlock);
|
||||
@@ -467,7 +483,9 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0);
|
||||
final NewBlockMessage futureAnnouncement =
|
||||
NewBlockMessage.create(
|
||||
futureBlock, getFullBlockchain().getTotalDifficultyByHash(futureBlock.getHash()).get());
|
||||
futureBlock,
|
||||
getFullBlockchain().getTotalDifficultyByHash(futureBlock.getHash()).get(),
|
||||
maxMessageSize);
|
||||
|
||||
// Broadcast
|
||||
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, futureAnnouncement);
|
||||
@@ -522,7 +540,8 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
|
||||
// Setup peer and messages
|
||||
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0);
|
||||
final NewBlockMessage oldAnnouncement = NewBlockMessage.create(oldBlock, Difficulty.ZERO);
|
||||
final NewBlockMessage oldAnnouncement =
|
||||
NewBlockMessage.create(oldBlock, Difficulty.ZERO, maxMessageSize);
|
||||
|
||||
// Broadcast
|
||||
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, oldAnnouncement);
|
||||
@@ -559,7 +578,7 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
blockPropagationManager.start();
|
||||
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0);
|
||||
final NewBlockMessage blockAnnouncementMsg =
|
||||
NewBlockMessage.create(blockToPurge, Difficulty.ZERO);
|
||||
NewBlockMessage.create(blockToPurge, Difficulty.ZERO, maxMessageSize);
|
||||
|
||||
// Broadcast
|
||||
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, blockAnnouncementMsg);
|
||||
@@ -597,7 +616,8 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHeader().getParentHash()).get();
|
||||
final Difficulty totalDifficulty =
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get();
|
||||
final NewBlockMessage nextAnnouncement = NewBlockMessage.create(nextBlock, totalDifficulty);
|
||||
final NewBlockMessage nextAnnouncement =
|
||||
NewBlockMessage.create(nextBlock, totalDifficulty, maxMessageSize);
|
||||
|
||||
// Broadcast message
|
||||
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, nextAnnouncement);
|
||||
@@ -735,7 +755,8 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
|
||||
final Difficulty totalDifficulty =
|
||||
getFullBlockchain().getTotalDifficultyByHash(block.getHash()).get();
|
||||
final NewBlockMessage newBlockMessage = NewBlockMessage.create(block, totalDifficulty);
|
||||
final NewBlockMessage newBlockMessage =
|
||||
NewBlockMessage.create(block, totalDifficulty, maxMessageSize);
|
||||
|
||||
// Broadcast message
|
||||
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlockMessage);
|
||||
@@ -933,7 +954,9 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0);
|
||||
final NewBlockMessage nextAnnouncement =
|
||||
NewBlockMessage.create(
|
||||
nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get());
|
||||
nextBlock,
|
||||
getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(),
|
||||
maxMessageSize);
|
||||
final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain());
|
||||
|
||||
syncState.setReachedTerminalDifficulty(true);
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection;
|
||||
import org.hyperledger.besu.util.number.ByteUnits;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Stream;
|
||||
@@ -38,6 +39,8 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
public class BlockBroadcasterTest {
|
||||
|
||||
final int maxMessageSize = 10 * ByteUnits.MEGABYTE;
|
||||
|
||||
@Test
|
||||
public void blockPropagationUnitTest() throws PeerConnection.PeerNotConnected {
|
||||
final EthPeer ethPeer = mock(EthPeer.class);
|
||||
@@ -47,10 +50,10 @@ public class BlockBroadcasterTest {
|
||||
final EthContext ethContext = mock(EthContext.class);
|
||||
when(ethContext.getEthPeers()).thenReturn(ethPeers);
|
||||
|
||||
final BlockBroadcaster blockBroadcaster = new BlockBroadcaster(ethContext);
|
||||
final BlockBroadcaster blockBroadcaster = new BlockBroadcaster(ethContext, maxMessageSize);
|
||||
final Block block = generateBlock();
|
||||
final NewBlockMessage newBlockMessage =
|
||||
NewBlockMessage.create(block, block.getHeader().getDifficulty());
|
||||
NewBlockMessage.create(block, block.getHeader().getDifficulty(), maxMessageSize);
|
||||
|
||||
blockBroadcaster.propagate(block, Difficulty.ZERO);
|
||||
|
||||
@@ -70,10 +73,10 @@ public class BlockBroadcasterTest {
|
||||
final EthContext ethContext = mock(EthContext.class);
|
||||
when(ethContext.getEthPeers()).thenReturn(ethPeers);
|
||||
|
||||
final BlockBroadcaster blockBroadcaster = new BlockBroadcaster(ethContext);
|
||||
final BlockBroadcaster blockBroadcaster = new BlockBroadcaster(ethContext, maxMessageSize);
|
||||
final Block block = generateBlock();
|
||||
final NewBlockMessage newBlockMessage =
|
||||
NewBlockMessage.create(block, block.getHeader().getDifficulty());
|
||||
NewBlockMessage.create(block, block.getHeader().getDifficulty(), maxMessageSize);
|
||||
|
||||
blockBroadcaster.propagate(block, Difficulty.ZERO);
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncTarget;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.tasks.exceptions.InvalidBlockException;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.services.pipeline.Pipeline;
|
||||
|
||||
@@ -69,13 +70,15 @@ public class PipelineChainDownloaderTest {
|
||||
public void setUp() {
|
||||
syncTarget = new SyncTarget(peer1, commonAncestor);
|
||||
syncTarget2 = new SyncTarget(peer2, commonAncestor);
|
||||
final NoOpMetricsSystem noOpMetricsSystem = new NoOpMetricsSystem();
|
||||
chainDownloader =
|
||||
new PipelineChainDownloader(
|
||||
syncState,
|
||||
syncTargetManager,
|
||||
downloadPipelineFactory,
|
||||
scheduler,
|
||||
new NoOpMetricsSystem());
|
||||
noOpMetricsSystem,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldSt
|
||||
import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
|
||||
@@ -141,7 +142,8 @@ public class CheckPointSyncChainDownloaderTest {
|
||||
ethContext,
|
||||
syncState,
|
||||
new NoOpMetricsSystem(),
|
||||
new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get()));
|
||||
new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get()),
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldSt
|
||||
import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
|
||||
@@ -115,7 +116,8 @@ public class FastDownloaderFactoryTest {
|
||||
ethContext,
|
||||
worldStateStorageCoordinator,
|
||||
syncState,
|
||||
clock))
|
||||
clock,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.isInstanceOf(IllegalStateException.class);
|
||||
}
|
||||
|
||||
@@ -139,7 +141,8 @@ public class FastDownloaderFactoryTest {
|
||||
ethContext,
|
||||
worldStateStorageCoordinator,
|
||||
syncState,
|
||||
clock);
|
||||
clock,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
assertThat(result).isEmpty();
|
||||
}
|
||||
|
||||
@@ -166,7 +169,8 @@ public class FastDownloaderFactoryTest {
|
||||
ethContext,
|
||||
worldStateStorageCoordinator,
|
||||
syncState,
|
||||
clock);
|
||||
clock,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
|
||||
verify(mutableBlockchain).getChainHeadBlockNumber();
|
||||
}
|
||||
@@ -200,7 +204,8 @@ public class FastDownloaderFactoryTest {
|
||||
ethContext,
|
||||
worldStateStorageCoordinator,
|
||||
syncState,
|
||||
clock);
|
||||
clock,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
|
||||
verify(worldStateKeyValueStorage).clear();
|
||||
assertThat(Files.exists(stateQueueDir)).isFalse();
|
||||
@@ -236,7 +241,8 @@ public class FastDownloaderFactoryTest {
|
||||
ethContext,
|
||||
worldStateStorageCoordinator,
|
||||
syncState,
|
||||
clock))
|
||||
clock,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.isInstanceOf(IllegalStateException.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
|
||||
@@ -111,7 +112,8 @@ public class FastSyncChainDownloaderTest {
|
||||
ethContext,
|
||||
syncState,
|
||||
new NoOpMetricsSystem(),
|
||||
new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get()));
|
||||
new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get()),
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldSt
|
||||
import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
import org.hyperledger.besu.services.tasks.TaskCollection;
|
||||
|
||||
@@ -105,7 +106,8 @@ public class FastSyncDownloaderTest {
|
||||
storage,
|
||||
taskCollection,
|
||||
fastSyncDataDirectory,
|
||||
FastSyncState.EMPTY_SYNC_STATE);
|
||||
FastSyncState.EMPTY_SYNC_STATE,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -119,7 +121,8 @@ public class FastSyncDownloaderTest {
|
||||
.thenReturn(completedFuture(selectPivotBlockState));
|
||||
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState))
|
||||
.thenReturn(completedFuture(downloadPivotBlockHeaderState));
|
||||
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(completedFuture(null));
|
||||
when(worldStateDownloader.run(
|
||||
@@ -131,7 +134,9 @@ public class FastSyncDownloaderTest {
|
||||
verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState);
|
||||
verify(storage).storeState(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(chainDownloader).start();
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)));
|
||||
@@ -148,7 +153,9 @@ public class FastSyncDownloaderTest {
|
||||
final CompletableFuture<FastSyncState> complete = completedFuture(fastSyncState);
|
||||
when(fastSyncActions.selectPivotBlock(fastSyncState)).thenReturn(complete);
|
||||
when(fastSyncActions.downloadPivotBlockHeader(fastSyncState)).thenReturn(complete);
|
||||
when(fastSyncActions.createChainDownloader(fastSyncState)).thenReturn(chainDownloader);
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
fastSyncState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(completedFuture(null));
|
||||
when(worldStateDownloader.run(
|
||||
any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))))
|
||||
@@ -162,14 +169,16 @@ public class FastSyncDownloaderTest {
|
||||
storage,
|
||||
taskCollection,
|
||||
fastSyncDataDirectory,
|
||||
fastSyncState);
|
||||
fastSyncState,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
|
||||
final CompletableFuture<FastSyncState> result = resumedDownloader.start();
|
||||
|
||||
verify(fastSyncActions).selectPivotBlock(fastSyncState);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(fastSyncState);
|
||||
verify(storage).storeState(fastSyncState);
|
||||
verify(fastSyncActions).createChainDownloader(fastSyncState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(fastSyncState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(chainDownloader).start();
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)));
|
||||
@@ -206,7 +215,8 @@ public class FastSyncDownloaderTest {
|
||||
.thenReturn(completedFuture(selectPivotBlockState));
|
||||
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState))
|
||||
.thenReturn(completedFuture(downloadPivotBlockHeaderState));
|
||||
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(chainFuture);
|
||||
when(worldStateDownloader.run(
|
||||
@@ -218,7 +228,9 @@ public class FastSyncDownloaderTest {
|
||||
verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState);
|
||||
verify(storage).storeState(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)));
|
||||
verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage);
|
||||
@@ -246,7 +258,8 @@ public class FastSyncDownloaderTest {
|
||||
.thenReturn(completedFuture(selectPivotBlockState));
|
||||
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState))
|
||||
.thenReturn(completedFuture(downloadPivotBlockHeaderState));
|
||||
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(chainFuture);
|
||||
when(worldStateDownloader.run(
|
||||
@@ -257,7 +270,9 @@ public class FastSyncDownloaderTest {
|
||||
|
||||
verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState);
|
||||
verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)));
|
||||
verifyNoMoreInteractions(fastSyncActions);
|
||||
@@ -321,7 +336,8 @@ public class FastSyncDownloaderTest {
|
||||
.thenReturn(completedFuture(selectPivotBlockState));
|
||||
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState))
|
||||
.thenReturn(completedFuture(downloadPivotBlockHeaderState));
|
||||
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(chainFuture);
|
||||
when(worldStateDownloader.run(
|
||||
@@ -332,7 +348,9 @@ public class FastSyncDownloaderTest {
|
||||
|
||||
verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState);
|
||||
verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)));
|
||||
verifyNoMoreInteractions(fastSyncActions);
|
||||
@@ -359,7 +377,8 @@ public class FastSyncDownloaderTest {
|
||||
.thenReturn(completedFuture(selectPivotBlockState));
|
||||
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState))
|
||||
.thenReturn(completedFuture(downloadPivotBlockHeaderState));
|
||||
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(chainFuture);
|
||||
when(worldStateDownloader.run(
|
||||
@@ -370,7 +389,9 @@ public class FastSyncDownloaderTest {
|
||||
|
||||
verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState);
|
||||
verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)));
|
||||
verifyNoMoreInteractions(fastSyncActions);
|
||||
@@ -407,7 +428,8 @@ public class FastSyncDownloaderTest {
|
||||
completedFuture(selectPivotBlockState), completedFuture(secondSelectPivotBlockState));
|
||||
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState))
|
||||
.thenReturn(completedFuture(downloadPivotBlockHeaderState));
|
||||
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(chainFuture);
|
||||
when(worldStateDownloader.run(
|
||||
@@ -418,7 +440,8 @@ public class FastSyncDownloaderTest {
|
||||
when(fastSyncActions.downloadPivotBlockHeader(secondSelectPivotBlockState))
|
||||
.thenReturn(completedFuture(secondDownloadPivotBlockHeaderState));
|
||||
|
||||
when(fastSyncActions.createChainDownloader(secondDownloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(secondChainDownloader);
|
||||
when(secondChainDownloader.start()).thenReturn(completedFuture(null));
|
||||
when(worldStateDownloader.run(
|
||||
@@ -430,7 +453,9 @@ public class FastSyncDownloaderTest {
|
||||
verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState);
|
||||
verify(storage).storeState(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)));
|
||||
verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage);
|
||||
@@ -446,7 +471,9 @@ public class FastSyncDownloaderTest {
|
||||
verify(fastSyncActions, times(2)).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(secondSelectPivotBlockState);
|
||||
verify(storage).storeState(secondDownloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions).createChainDownloader(secondDownloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(
|
||||
secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(secondPivotBlockHeader)));
|
||||
verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage);
|
||||
@@ -481,7 +508,8 @@ public class FastSyncDownloaderTest {
|
||||
completedFuture(selectPivotBlockState), completedFuture(secondSelectPivotBlockState));
|
||||
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState))
|
||||
.thenReturn(completedFuture(downloadPivotBlockHeaderState));
|
||||
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(chainFuture);
|
||||
when(worldStateDownloader.run(
|
||||
@@ -494,7 +522,8 @@ public class FastSyncDownloaderTest {
|
||||
when(fastSyncActions.downloadPivotBlockHeader(secondSelectPivotBlockState))
|
||||
.thenReturn(completedFuture(secondDownloadPivotBlockHeaderState));
|
||||
|
||||
when(fastSyncActions.createChainDownloader(secondDownloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(secondChainDownloader);
|
||||
when(secondChainDownloader.start()).thenReturn(completedFuture(null));
|
||||
when(worldStateDownloader.run(
|
||||
@@ -506,7 +535,9 @@ public class FastSyncDownloaderTest {
|
||||
verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState);
|
||||
verify(storage).storeState(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)));
|
||||
verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage);
|
||||
@@ -524,7 +555,9 @@ public class FastSyncDownloaderTest {
|
||||
verify(fastSyncActions, times(2)).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
|
||||
verify(fastSyncActions).downloadPivotBlockHeader(secondSelectPivotBlockState);
|
||||
verify(storage).storeState(secondDownloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions).createChainDownloader(secondDownloadPivotBlockHeaderState);
|
||||
verify(fastSyncActions)
|
||||
.createChainDownloader(
|
||||
secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
verify(worldStateDownloader)
|
||||
.run(any(FastSyncActions.class), eq(new FastSyncState(secondPivotBlockHeader)));
|
||||
verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage);
|
||||
@@ -556,7 +589,8 @@ public class FastSyncDownloaderTest {
|
||||
.thenReturn(completedFuture(selectPivotBlockState));
|
||||
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState))
|
||||
.thenReturn(completedFuture(downloadPivotBlockHeaderState));
|
||||
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(new CompletableFuture<>());
|
||||
when(worldStateDownloader.run(
|
||||
@@ -581,7 +615,8 @@ public class FastSyncDownloaderTest {
|
||||
.thenReturn(completedFuture(selectPivotBlockState));
|
||||
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState))
|
||||
.thenReturn(completedFuture(downloadPivotBlockHeaderState));
|
||||
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState))
|
||||
when(fastSyncActions.createChainDownloader(
|
||||
downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS))
|
||||
.thenReturn(chainDownloader);
|
||||
when(chainDownloader.start()).thenReturn(completedFuture(null));
|
||||
when(worldStateDownloader.run(
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValu
|
||||
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
|
||||
@@ -100,7 +101,8 @@ public class FastWorldDownloadStateTest {
|
||||
pendingRequests,
|
||||
MAX_REQUESTS_WITHOUT_PROGRESS,
|
||||
MIN_MILLIS_BEFORE_STALLING,
|
||||
clock);
|
||||
clock,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
assertThat(downloadState.isDownloading()).isTrue();
|
||||
downloadState.setRootNodeData(ROOT_NODE_DATA);
|
||||
future = downloadState.getDownloadFuture();
|
||||
|
||||
@@ -64,6 +64,7 @@ import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.account.AccountStorageEntry;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldState;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
|
||||
import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues;
|
||||
@@ -1051,7 +1052,8 @@ class FastWorldStateDownloaderTest {
|
||||
config.getWorldStateMaxRequestsWithoutProgress(),
|
||||
config.getWorldStateMinMillisBeforeStalling(),
|
||||
TestClock.fixed(),
|
||||
new NoOpMetricsSystem());
|
||||
new NoOpMetricsSystem(),
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
private WorldStatePreimageStorage createPreimageStorage() {
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
@@ -89,7 +90,8 @@ public class FullSyncChainDownloaderForkTest {
|
||||
ethContext,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
SyncTerminationCondition.never());
|
||||
SyncTerminationCondition.never(),
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
private ChainDownloader downloader() {
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
@@ -121,7 +122,8 @@ public class FullSyncChainDownloaderTest {
|
||||
ethContext,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
SyncTerminationCondition.never());
|
||||
SyncTerminationCondition.never(),
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
private ChainDownloader downloader() {
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.eth.sync.ChainDownloader;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
@@ -107,7 +108,8 @@ public class FullSyncChainDownloaderTotalTerminalDifficultyTest {
|
||||
ethContext,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
terminalCondition);
|
||||
terminalCondition,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
private SynchronizerConfiguration.Builder syncConfigBuilder() {
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
@@ -96,7 +97,8 @@ public class FullSyncDownloaderTest {
|
||||
ethContext,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
SyncTerminationCondition.never());
|
||||
SyncTerminationCondition.never(),
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValu
|
||||
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.SyncDurationMetrics;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
|
||||
@@ -137,7 +138,8 @@ public class SnapWorldDownloadStateTest {
|
||||
MIN_MILLIS_BEFORE_STALLING,
|
||||
metricsManager,
|
||||
clock,
|
||||
ethContext);
|
||||
ethContext,
|
||||
SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS);
|
||||
final DynamicPivotBlockSelector dynamicPivotBlockManager =
|
||||
mock(DynamicPivotBlockSelector.class);
|
||||
doAnswer(
|
||||
|
||||
@@ -126,9 +126,13 @@ public class CodeValidateSubCommand implements Runnable {
|
||||
private void checkCodeFromBufferedReader(final BufferedReader in) {
|
||||
try {
|
||||
for (String code = in.readLine(); code != null; code = in.readLine()) {
|
||||
String validation = considerCode(code);
|
||||
if (!Strings.isBlank(validation)) {
|
||||
parentCommand.out.println(validation);
|
||||
try {
|
||||
String validation = considerCode(code);
|
||||
if (!Strings.isBlank(validation)) {
|
||||
parentCommand.out.println(validation);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
parentCommand.out.println("fail: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -151,14 +155,17 @@ public class CodeValidateSubCommand implements Runnable {
|
||||
public String considerCode(final String hexCode) {
|
||||
Bytes codeBytes;
|
||||
try {
|
||||
codeBytes =
|
||||
Bytes.fromHexString(
|
||||
hexCode.replaceAll("(^|\n)#[^\n]*($|\n)", "").replaceAll("[^0-9A-Za-z]", ""));
|
||||
String strippedString =
|
||||
hexCode.replaceAll("(^|\n)#[^\n]*($|\n)", "").replaceAll("[^0-9A-Za-z]", "");
|
||||
if (Strings.isEmpty(strippedString)) {
|
||||
return "";
|
||||
}
|
||||
codeBytes = Bytes.fromHexString(strippedString);
|
||||
} catch (RuntimeException re) {
|
||||
return "err: hex string -" + re;
|
||||
}
|
||||
if (codeBytes.isEmpty()) {
|
||||
return "";
|
||||
return "err: empty container";
|
||||
}
|
||||
|
||||
EOFLayout layout = evm.get().parseEOF(codeBytes);
|
||||
|
||||
@@ -89,7 +89,13 @@ public class PrettyPrintSubCommand implements Runnable {
|
||||
LogConfigurator.setLevel("", "OFF");
|
||||
|
||||
for (var hexCode : codeList) {
|
||||
Bytes container = Bytes.fromHexString(hexCode);
|
||||
Bytes container;
|
||||
try {
|
||||
container = Bytes.fromHexString(hexCode);
|
||||
} catch (IllegalArgumentException e) {
|
||||
parentCommand.out.println("Invalid hex string: " + e.getMessage());
|
||||
continue;
|
||||
}
|
||||
if (container.get(0) != ((byte) 0xef) && container.get(1) != 0) {
|
||||
parentCommand.out.println(
|
||||
"Pretty printing of legacy EVM is not supported. Patches welcome!");
|
||||
|
||||
@@ -14,13 +14,10 @@
|
||||
*/
|
||||
package org.hyperledger.besu.evm;
|
||||
|
||||
import static org.hyperledger.besu.evm.MainnetEVMs.SHANGHAI_INIT_CODE_SIZE_LIMIT;
|
||||
import static org.hyperledger.besu.evm.MainnetEVMs.registerIstanbulOperations;
|
||||
|
||||
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import org.hyperledger.besu.evm.operation.Create2Operation;
|
||||
import org.hyperledger.besu.evm.operation.CreateOperation;
|
||||
import org.hyperledger.besu.evm.operation.OperationRegistry;
|
||||
import org.hyperledger.besu.evm.operation.Push0Operation;
|
||||
|
||||
@@ -62,8 +59,6 @@ public class ClassicEVMs {
|
||||
OperationRegistry registry = new OperationRegistry();
|
||||
registerIstanbulOperations(registry, gasCalculator, chainId);
|
||||
registry.put(new Push0Operation(gasCalculator));
|
||||
registry.put(new CreateOperation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT));
|
||||
registry.put(new Create2Operation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT));
|
||||
return registry;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,12 +150,6 @@ public class MainnetEVMs {
|
||||
/** The constant DEV_NET_CHAIN_ID. */
|
||||
public static final BigInteger DEV_NET_CHAIN_ID = BigInteger.valueOf(1337);
|
||||
|
||||
/** The constant SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT. */
|
||||
public static final int SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT = 0x6000;
|
||||
|
||||
/** The constant SHANGHAI_INIT_CODE_SIZE_LIMIT. */
|
||||
public static final int SHANGHAI_INIT_CODE_SIZE_LIMIT = 2 * SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT;
|
||||
|
||||
private MainnetEVMs() {
|
||||
// utility class
|
||||
}
|
||||
@@ -267,7 +261,7 @@ public class MainnetEVMs {
|
||||
registry.put(new InvalidOperation(gasCalculator));
|
||||
registry.put(new StopOperation(gasCalculator));
|
||||
registry.put(new SelfDestructOperation(gasCalculator));
|
||||
registry.put(new CreateOperation(gasCalculator, Integer.MAX_VALUE));
|
||||
registry.put(new CreateOperation(gasCalculator));
|
||||
registry.put(new CallOperation(gasCalculator));
|
||||
registry.put(new CallCodeOperation(gasCalculator));
|
||||
|
||||
@@ -477,7 +471,7 @@ public class MainnetEVMs {
|
||||
public static void registerConstantinopleOperations(
|
||||
final OperationRegistry registry, final GasCalculator gasCalculator) {
|
||||
registerByzantiumOperations(registry, gasCalculator);
|
||||
registry.put(new Create2Operation(gasCalculator, Integer.MAX_VALUE));
|
||||
registry.put(new Create2Operation(gasCalculator));
|
||||
registry.put(new SarOperation(gasCalculator));
|
||||
registry.put(new ShlOperation(gasCalculator));
|
||||
registry.put(new ShrOperation(gasCalculator));
|
||||
@@ -812,8 +806,6 @@ public class MainnetEVMs {
|
||||
final BigInteger chainID) {
|
||||
registerParisOperations(registry, gasCalculator, chainID);
|
||||
registry.put(new Push0Operation(gasCalculator));
|
||||
registry.put(new CreateOperation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT));
|
||||
registry.put(new Create2Operation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -740,35 +740,59 @@ public record EOFLayout(
|
||||
OpcodeInfo ci = V1_OPCODES[byteCode[pc] & 0xff];
|
||||
|
||||
if (ci.opcode() == RelativeJumpVectorOperation.OPCODE) {
|
||||
int tableSize = byteCode[pc + 1] & 0xff;
|
||||
out.printf("%02x%02x", byteCode[pc], byteCode[pc + 1]);
|
||||
for (int j = 0; j <= tableSize; j++) {
|
||||
out.printf("%02x%02x", byteCode[pc + j * 2 + 2], byteCode[pc + j * 2 + 3]);
|
||||
}
|
||||
out.printf(" # [%d] %s(", pc, ci.name());
|
||||
for (int j = 0; j <= tableSize; j++) {
|
||||
if (j != 0) {
|
||||
out.print(',');
|
||||
if (byteCode.length <= pc + 1) {
|
||||
out.printf(
|
||||
" %02x # [%d] %s(<truncated instruction>)%n", byteCode[pc], pc, ci.name());
|
||||
pc++;
|
||||
} else {
|
||||
int tableSize = byteCode[pc + 1] & 0xff;
|
||||
out.printf("%02x%02x", byteCode[pc], byteCode[pc + 1]);
|
||||
int calculatedTableEnd = pc + tableSize * 2 + 4;
|
||||
int lastTableEntry = Math.min(byteCode.length, calculatedTableEnd);
|
||||
for (int j = pc + 2; j < lastTableEntry; j++) {
|
||||
out.printf("%02x", byteCode[j]);
|
||||
}
|
||||
int b0 = byteCode[pc + j * 2 + 2]; // we want the sign extension, so no `& 0xff`
|
||||
int b1 = byteCode[pc + j * 2 + 3] & 0xff;
|
||||
out.print(b0 << 8 | b1);
|
||||
out.printf(" # [%d] %s(", pc, ci.name());
|
||||
for (int j = pc + 3; j < lastTableEntry; j += 2) {
|
||||
// j indexes to the second byte of the word, to handle mid-word truncation
|
||||
if (j != pc + 3) {
|
||||
out.print(',');
|
||||
}
|
||||
int b0 = byteCode[j - 1]; // we want the sign extension, so no `& 0xff`
|
||||
int b1 = byteCode[j] & 0xff;
|
||||
out.print(b0 << 8 | b1);
|
||||
}
|
||||
if (byteCode.length < calculatedTableEnd) {
|
||||
out.print("<truncated immediate>");
|
||||
}
|
||||
pc += tableSize * 2 + 4;
|
||||
out.print(")\n");
|
||||
}
|
||||
pc += tableSize * 2 + 4;
|
||||
out.print(")\n");
|
||||
} else if (ci.opcode() == RelativeJumpOperation.OPCODE
|
||||
|| ci.opcode() == RelativeJumpIfOperation.OPCODE) {
|
||||
int b0 = byteCode[pc + 1] & 0xff;
|
||||
int b1 = byteCode[pc + 2] & 0xff;
|
||||
short delta = (short) (b0 << 8 | b1);
|
||||
out.printf("%02x%02x%02x # [%d] %s(%d)", byteCode[pc], b0, b1, pc, ci.name(), delta);
|
||||
if (pc + 1 >= byteCode.length) {
|
||||
out.printf(" %02x # [%d] %s(<truncated immediate>)", byteCode[pc], pc, ci.name());
|
||||
} else if (pc + 2 >= byteCode.length) {
|
||||
out.printf(
|
||||
" %02x%02x # [%d] %s(<truncated immediate>)",
|
||||
byteCode[pc], byteCode[pc + 1], pc, ci.name());
|
||||
} else {
|
||||
int b0 = byteCode[pc + 1] & 0xff;
|
||||
int b1 = byteCode[pc + 2] & 0xff;
|
||||
short delta = (short) (b0 << 8 | b1);
|
||||
out.printf("%02x%02x%02x # [%d] %s(%d)", byteCode[pc], b0, b1, pc, ci.name(), delta);
|
||||
}
|
||||
pc += 3;
|
||||
out.printf("%n");
|
||||
} else if (ci.opcode() == ExchangeOperation.OPCODE) {
|
||||
int imm = byteCode[pc + 1] & 0xff;
|
||||
out.printf(
|
||||
" %02x%02x # [%d] %s(%d, %d)",
|
||||
byteCode[pc], imm, pc, ci.name(), imm >> 4, imm & 0x0F);
|
||||
if (pc + 1 >= byteCode.length) {
|
||||
out.printf(" %02x # [%d] %s(<truncated immediate>)", byteCode[pc], pc, ci.name());
|
||||
} else {
|
||||
int imm = byteCode[pc + 1] & 0xff;
|
||||
out.printf(
|
||||
" %02x%02x # [%d] %s(%d, %d)",
|
||||
byteCode[pc], imm, pc, ci.name(), imm >> 4, imm & 0x0F);
|
||||
}
|
||||
pc += 2;
|
||||
out.printf("%n");
|
||||
} else {
|
||||
@@ -784,7 +808,11 @@ public record EOFLayout(
|
||||
}
|
||||
out.printf(" # [%d] %s", pc, ci.name());
|
||||
if (advance == 2) {
|
||||
out.printf("(%d)", byteCode[pc + 1] & 0xff);
|
||||
if (byteCode.length <= pc + 1) {
|
||||
out.print("(<truncated immediate>)");
|
||||
} else {
|
||||
out.printf("(%d)", byteCode[pc + 1] & 0xff);
|
||||
}
|
||||
} else if (advance > 2) {
|
||||
out.print("(0x");
|
||||
for (int j = 1; j < advance && (pc + j) < byteCode.length; j++) {
|
||||
|
||||
@@ -45,9 +45,6 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
|
||||
protected static final OperationResult INVALID_OPERATION =
|
||||
new OperationResult(0L, ExceptionalHaltReason.INVALID_OPERATION);
|
||||
|
||||
/** The maximum init code size */
|
||||
protected final int maxInitcodeSize;
|
||||
|
||||
/** The EOF Version this create operation requires initcode to be in */
|
||||
protected final int eofVersion;
|
||||
|
||||
@@ -59,7 +56,6 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
|
||||
* @param stackItemsConsumed the stack items consumed
|
||||
* @param stackItemsProduced the stack items produced
|
||||
* @param gasCalculator the gas calculator
|
||||
* @param maxInitcodeSize Maximum init code size
|
||||
* @param eofVersion the EOF version this create operation is valid in
|
||||
*/
|
||||
protected AbstractCreateOperation(
|
||||
@@ -68,10 +64,8 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
|
||||
final int stackItemsConsumed,
|
||||
final int stackItemsProduced,
|
||||
final GasCalculator gasCalculator,
|
||||
final int maxInitcodeSize,
|
||||
final int eofVersion) {
|
||||
super(opcode, name, stackItemsConsumed, stackItemsProduced, gasCalculator);
|
||||
this.maxInitcodeSize = maxInitcodeSize;
|
||||
this.eofVersion = eofVersion;
|
||||
}
|
||||
|
||||
@@ -103,7 +97,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
|
||||
|
||||
Code code = codeSupplier.get();
|
||||
|
||||
if (code != null && code.getSize() > maxInitcodeSize) {
|
||||
if (code != null && code.getSize() > evm.getEvmVersion().getMaxInitcodeSize()) {
|
||||
frame.popStackItems(getStackItemsConsumed());
|
||||
return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE);
|
||||
}
|
||||
|
||||
@@ -39,10 +39,9 @@ public class Create2Operation extends AbstractCreateOperation {
|
||||
* Instantiates a new Create2 operation.
|
||||
*
|
||||
* @param gasCalculator the gas calculator
|
||||
* @param maxInitcodeSize Maximum init code size
|
||||
*/
|
||||
public Create2Operation(final GasCalculator gasCalculator, final int maxInitcodeSize) {
|
||||
super(0xF5, "CREATE2", 4, 1, gasCalculator, maxInitcodeSize, 0);
|
||||
public Create2Operation(final GasCalculator gasCalculator) {
|
||||
super(0xF5, "CREATE2", 4, 1, gasCalculator, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -36,10 +36,9 @@ public class CreateOperation extends AbstractCreateOperation {
|
||||
* Instantiates a new Create operation.
|
||||
*
|
||||
* @param gasCalculator the gas calculator
|
||||
* @param maxInitcodeSize Maximum init code size
|
||||
*/
|
||||
public CreateOperation(final GasCalculator gasCalculator, final int maxInitcodeSize) {
|
||||
super(0xF0, "CREATE", 3, 1, gasCalculator, maxInitcodeSize, 0);
|
||||
public CreateOperation(final GasCalculator gasCalculator) {
|
||||
super(0xF0, "CREATE", 3, 1, gasCalculator, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,7 +44,7 @@ public class EOFCreateOperation extends AbstractCreateOperation {
|
||||
* @param gasCalculator the gas calculator
|
||||
*/
|
||||
public EOFCreateOperation(final GasCalculator gasCalculator) {
|
||||
super(OPCODE, "EOFCREATE", 4, 1, gasCalculator, Integer.MAX_VALUE, 1);
|
||||
super(OPCODE, "EOFCREATE", 4, 1, gasCalculator, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -38,6 +38,7 @@ public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledCont
|
||||
new BigInteger(
|
||||
"115792089237316195423570985008687907853269984665640564039457584007913129639935");
|
||||
|
||||
private static final Bytes POINT_AT_INFINITY = Bytes.repeat((byte) 0, 64);
|
||||
private final long gasCost;
|
||||
|
||||
private AltBN128MulPrecompiledContract(final GasCalculator gasCalculator, final long gasCost) {
|
||||
@@ -78,6 +79,12 @@ public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledCont
|
||||
@Override
|
||||
public PrecompileContractResult computePrecompile(
|
||||
final Bytes input, @Nonnull final MessageFrame messageFrame) {
|
||||
|
||||
if (input.size() >= 64 && input.slice(0, 64).equals(POINT_AT_INFINITY)) {
|
||||
return new PrecompileContractResult(
|
||||
POINT_AT_INFINITY, false, MessageFrame.State.COMPLETED_SUCCESS, Optional.empty());
|
||||
}
|
||||
|
||||
if (useNative) {
|
||||
return computeNative(input, messageFrame);
|
||||
} else {
|
||||
|
||||
@@ -57,7 +57,7 @@ class AbstractCreateOperationTest {
|
||||
private final MutableAccount account = mock(MutableAccount.class);
|
||||
private final MutableAccount newAccount = mock(MutableAccount.class);
|
||||
private final FakeCreateOperation operation =
|
||||
new FakeCreateOperation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE);
|
||||
new FakeCreateOperation(new ConstantinopleGasCalculator());
|
||||
|
||||
private static final Bytes SIMPLE_CREATE =
|
||||
Bytes.fromHexString(
|
||||
@@ -100,10 +100,9 @@ class AbstractCreateOperationTest {
|
||||
* Instantiates a new Create operation.
|
||||
*
|
||||
* @param gasCalculator the gas calculator
|
||||
* @param maxInitcodeSize Maximum init code size
|
||||
*/
|
||||
public FakeCreateOperation(final GasCalculator gasCalculator, final int maxInitcodeSize) {
|
||||
super(0xEF, "FAKECREATE", 3, 1, gasCalculator, maxInitcodeSize, 0);
|
||||
public FakeCreateOperation(final GasCalculator gasCalculator) {
|
||||
super(0xEF, "FAKECREATE", 3, 1, gasCalculator, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,11 +60,7 @@ public class Create2OperationTest {
|
||||
private final MutableAccount newAccount = mock(MutableAccount.class);
|
||||
|
||||
private final Create2Operation operation =
|
||||
new Create2Operation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE);
|
||||
|
||||
private final Create2Operation maxInitCodeOperation =
|
||||
new Create2Operation(
|
||||
new ConstantinopleGasCalculator(), MainnetEVMs.SHANGHAI_INIT_CODE_SIZE_LIMIT);
|
||||
new Create2Operation(new ConstantinopleGasCalculator());
|
||||
|
||||
private static final String TOPIC =
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // 32 FFs
|
||||
@@ -221,7 +217,7 @@ public class Create2OperationTest {
|
||||
when(worldUpdater.updater()).thenReturn(worldUpdater);
|
||||
|
||||
final EVM myEVM = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT);
|
||||
var result = maxInitCodeOperation.execute(messageFrame, myEVM);
|
||||
var result = operation.execute(messageFrame, myEVM);
|
||||
final MessageFrame createFrame = messageFrame.getMessageFrameStack().peek();
|
||||
final ContractCreationProcessor ccp =
|
||||
new ContractCreationProcessor(myEVM, false, List.of(), 0, List.of());
|
||||
@@ -250,7 +246,7 @@ public class Create2OperationTest {
|
||||
when(worldUpdater.updater()).thenReturn(worldUpdater);
|
||||
|
||||
final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT);
|
||||
var result = maxInitCodeOperation.execute(messageFrame, evm);
|
||||
var result = operation.execute(messageFrame, evm);
|
||||
assertThat(result.getHaltReason()).isEqualTo(CODE_TOO_LARGE);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,12 +52,7 @@ class CreateOperationTest {
|
||||
private final WorldUpdater worldUpdater = mock(WorldUpdater.class);
|
||||
private final MutableAccount account = mock(MutableAccount.class);
|
||||
private final MutableAccount newAccount = mock(MutableAccount.class);
|
||||
private final CreateOperation operation =
|
||||
new CreateOperation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE);
|
||||
private final CreateOperation maxInitCodeOperation =
|
||||
new CreateOperation(
|
||||
new ConstantinopleGasCalculator(), MainnetEVMs.SHANGHAI_INIT_CODE_SIZE_LIMIT);
|
||||
private final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT);
|
||||
private final CreateOperation operation = new CreateOperation(new ConstantinopleGasCalculator());
|
||||
|
||||
private static final String TOPIC =
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // 32 FFs
|
||||
@@ -82,7 +77,7 @@ class CreateOperationTest {
|
||||
@Test
|
||||
void createFromMemoryMutationSafe() {
|
||||
|
||||
// Given: Execute a CREATE operation with a contract that logs in the constructor
|
||||
// Given: Execute a CREATE operation with a contract that logs in the constructor
|
||||
final UInt256 memoryOffset = UInt256.fromHexString("0xFF");
|
||||
final UInt256 memoryLength = UInt256.valueOf(SIMPLE_CREATE.size());
|
||||
final MessageFrame messageFrame = testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1);
|
||||
@@ -190,7 +185,7 @@ class CreateOperationTest {
|
||||
when(worldUpdater.updater()).thenReturn(worldUpdater);
|
||||
|
||||
final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT);
|
||||
var result = maxInitCodeOperation.execute(messageFrame, evm);
|
||||
var result = operation.execute(messageFrame, evm);
|
||||
final MessageFrame createFrame = messageFrame.getMessageFrameStack().peek();
|
||||
final ContractCreationProcessor ccp =
|
||||
new ContractCreationProcessor(evm, false, List.of(), 0, List.of());
|
||||
@@ -218,17 +213,18 @@ class CreateOperationTest {
|
||||
when(worldUpdater.updater()).thenReturn(worldUpdater);
|
||||
|
||||
final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT);
|
||||
var result = maxInitCodeOperation.execute(messageFrame, evm);
|
||||
var result = operation.execute(messageFrame, evm);
|
||||
assertThat(result.getHaltReason()).isEqualTo(CODE_TOO_LARGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void eofV1CannotCall() {
|
||||
final EVM pragueEvm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT);
|
||||
final UInt256 memoryOffset = UInt256.fromHexString("0xFF");
|
||||
final UInt256 memoryLength = UInt256.valueOf(SIMPLE_CREATE.size());
|
||||
final MessageFrame messageFrame =
|
||||
new TestMessageFrameBuilder()
|
||||
.code(evm.getCodeUncached(SIMPLE_EOF))
|
||||
.code(pragueEvm.getCodeUncached(SIMPLE_EOF))
|
||||
.pushStackItem(memoryLength)
|
||||
.pushStackItem(memoryOffset)
|
||||
.pushStackItem(Bytes.EMPTY)
|
||||
@@ -252,6 +248,7 @@ class CreateOperationTest {
|
||||
final UInt256 memoryLength,
|
||||
final UInt256 value,
|
||||
final int depth) {
|
||||
final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT);
|
||||
final MessageFrame messageFrame =
|
||||
MessageFrame.builder()
|
||||
.type(MessageFrame.Type.CONTRACT_CREATION)
|
||||
|
||||
@@ -4661,12 +4661,12 @@
|
||||
<sha256 value="6d535f94efb663bdb682c9f27a50335394688009642ba7a9677504bc1be4129b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="arithmetic" version="0.9.4">
|
||||
<artifact name="arithmetic-0.9.4.jar">
|
||||
<sha256 value="a4e3d7dc713aab83a0b1cb0ff32cb917fe92372bd794c320652c82ac3a765f23" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="arithmetic" version="0.9.5">
|
||||
<artifact name="arithmetic-0.9.5.jar">
|
||||
<sha256 value="900030f193ff728f9f8a031a5eb0c27d1372252e3718cb731e173d249f805656" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="arithmetic-0.9.4.module">
|
||||
<sha256 value="34e067d985b00f9a5fa60a0c7ed136e6abaa2da9c78512569c148df2936d88c2" origin="Generated by Gradle"/>
|
||||
<artifact name="arithmetic-0.9.5.module">
|
||||
<sha256 value="d3028250acc638de810789a179a7eecd8e545f8560e8c33b4c58db1fb5b60016" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="arithmetic-0.9.4.pom">
|
||||
<sha256 value="e6e8b07617950d9213752c4a02999417c1c7a1f349009ddbf1e1f64bba88f6d4" origin="Generated by Gradle"/>
|
||||
@@ -4680,70 +4680,61 @@
|
||||
<sha256 value="c273525c9f23a0bd5b9cf6830b4bebd9d81e355b7f2ed3a22f23f76c2a2313d5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="blake2bf" version="0.9.4">
|
||||
<artifact name="blake2bf-0.9.4.jar">
|
||||
<sha256 value="3b84f769f9dd5d5bc780d049116d781943ee176e153cc5aa8f2702ec2e7c100c" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="blake2bf" version="0.9.5">
|
||||
<artifact name="blake2bf-0.9.5.jar">
|
||||
<sha256 value="57075a2a487f86c4d4dd03036b0c756bcb26372f6348b98b1fad182d2588347a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="blake2bf-0.9.4.module">
|
||||
<sha256 value="a0921fdff76a962c1be185f2926f28a3c5476616f1b358a3f031fde5a896af72" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="blake2bf-0.9.4.pom">
|
||||
<sha256 value="69cfe6d53ec8267ba4f0ae90e6a80a770d1ed5b314c4e64a3c90b50ea7fe38d7" origin="Generated by Gradle"/>
|
||||
<artifact name="blake2bf-0.9.5.module">
|
||||
<sha256 value="e34cc40e065dbd790326f384c8fa3fff932dcd8b8dcc10b362d47b6520c1127e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="bls12-381" version="0.9.4">
|
||||
<artifact name="bls12-381-0.9.4.jar">
|
||||
<sha256 value="8d5cb9f39af3ebac073dd2da6154c043c52e630e528743644d9c427a2a85586c" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="bls12-381" version="0.9.5">
|
||||
<artifact name="bls12-381-0.9.5.jar">
|
||||
<sha256 value="9ddf732dc66e057d9d70d61ddfef09f85b4a7effa5909133b97f7d5284798ca2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="bls12-381-0.9.4.module">
|
||||
<sha256 value="408ce225a3a3ba1ab70407ca84498a50897e9b5b69621158a51f3f5c633b8cb6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="bls12-381-0.9.4.pom">
|
||||
<sha256 value="63a64994de9db57e6b193966fa6a0fa6c6b25abe938b11ad057d31dceea30ad7" origin="Generated by Gradle"/>
|
||||
<artifact name="bls12-381-0.9.5.module">
|
||||
<sha256 value="122d991e72dfa4fe086352b7adccaa92a9b5a5f4ffc36742c251309ee18408bb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="gnark" version="0.9.4">
|
||||
<artifact name="gnark-0.9.4.jar">
|
||||
<sha256 value="329d1ec37678ed97b9f11a079bbf439c46630fb9c0685d9a2a7c6374725a2b98" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="gnark" version="0.9.5">
|
||||
<artifact name="gnark-0.9.5.jar">
|
||||
<sha256 value="a5a2198b943b1e8ece5865622e6861891a682a8efa068b43f233284f220270f1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="gnark-0.9.4.module">
|
||||
<sha256 value="27befd6cc473e4f444a2803b6d473ef214b7d6931d3e5c437d3408e0b2f3515e" origin="Generated by Gradle"/>
|
||||
<artifact name="gnark-0.9.5.module">
|
||||
<sha256 value="91f02a8ddf882e06c2129251abc9bec33891cb49bc6cfde966b3ce62512e8e88" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="gnark-0.9.4.pom">
|
||||
<sha256 value="53205e59ee908a2f7a2f9373b4becc1776d11302f429c7d7080eb9ba08c2bdd8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="ipa-multipoint" version="0.9.4">
|
||||
<artifact name="ipa-multipoint-0.9.4.jar">
|
||||
<sha256 value="db30f98991401d7d3544e2bbe41906dda299fde7ac48a4e9bbfb4cbeef5ad7d4" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="ipa-multipoint" version="0.9.5">
|
||||
<artifact name="ipa-multipoint-0.9.5.jar">
|
||||
<sha256 value="f46bf590ef0aeb1e826de188ca60f6d575848dc84da8dd370584eaea2f3f3987" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ipa-multipoint-0.9.4.module">
|
||||
<sha256 value="88dc53b974bf3235d8cadb72fa71d40ca9c1ee86736dca60002e587271f10c32" origin="Generated by Gradle"/>
|
||||
<artifact name="ipa-multipoint-0.9.5.module">
|
||||
<sha256 value="f5437b695f978602036ef0e499f33807abbf277b9f1eaef5fc6cd3d0d2709b90" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ipa-multipoint-0.9.4.pom">
|
||||
<sha256 value="7733b56ca522dcb12060167a6081ece971587f5bbb0b1c18cc9d8b4cc0ff9fa3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="secp256k1" version="0.9.4">
|
||||
<artifact name="secp256k1-0.9.4.jar">
|
||||
<sha256 value="c2322ccc0a0d081924a3d8c84b4c45865b8cd2620fc7b2057318414c37bf0fef" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="secp256k1" version="0.9.5">
|
||||
<artifact name="secp256k1-0.9.5.jar">
|
||||
<sha256 value="02971cfcdd0d37b3cfccdf2a83e271b90eaf16887ee646c7a181c12cf3850502" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256k1-0.9.4.module">
|
||||
<sha256 value="0922171689524d2a0eea78f275d1d22baf4cd548e3e9f2652d9af99f16be25b8" origin="Generated by Gradle"/>
|
||||
<artifact name="secp256k1-0.9.5.module">
|
||||
<sha256 value="7114e638af2b63d20cda0156e4abdd9f55c1324060e3fa838f834c07f5f1b17f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256k1-0.9.4.pom">
|
||||
<sha256 value="1ec6215fdf4d51e34ffa8b7149607c2cda80601fcfe4177946a7b7fa305ca3c6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="secp256r1" version="0.9.4">
|
||||
<artifact name="secp256r1-0.9.4.pom">
|
||||
<sha256 value="407ca2c1b054ccf4211e29066b3f7b0c13f0615a75bda15af7f6447c16abf5c6" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="secp256r1" version="0.9.5">
|
||||
<artifact name="secp256r1-0.9.5.jar">
|
||||
<sha256 value="17eaf8c2e7316a4cacff7ccd7fe73301636c9763a6f27991381cde243e5f2682" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256r1-0.9.4.jar">
|
||||
<sha256 value="a9772d669870dd73ef518e8d35315ddd57f1be56d59d1e3ee29a72c7740f2823" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256r1-0.9.4.module">
|
||||
<sha256 value="c0083fa584ada62d8da3b7dc0abd325606f8df08da9c8f5d840f6e2f0f5bfd9c" origin="Generated by Gradle"/>
|
||||
<artifact name="secp256r1-0.9.5.module">
|
||||
<sha256 value="8307f5ccc92137787d3bc026a41da3bbc6b2978834fe1aa6d5a4593a493e6762" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.immutables" name="immutables" version="2.10.0">
|
||||
|
||||
@@ -156,7 +156,7 @@ dependencyManagement {
|
||||
|
||||
dependency 'org.fusesource.jansi:jansi:2.4.1'
|
||||
|
||||
dependencySet(group: 'org.hyperledger.besu', version: '0.9.4') {
|
||||
dependencySet(group: 'org.hyperledger.besu', version: '0.9.5') {
|
||||
entry 'arithmetic'
|
||||
entry 'ipa-multipoint'
|
||||
entry 'bls12-381'
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.metrics;
|
||||
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
|
||||
import org.hyperledger.besu.plugin.services.metrics.OperationTimer;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This class manages the synchronization duration metrics for the Hyperledger Besu project. It
|
||||
* provides methods to start and stop timers for various synchronization phases.
|
||||
*/
|
||||
public class SyncDurationMetrics {
|
||||
|
||||
/** A {@link SyncDurationMetrics} instance that does not record any metrics. */
|
||||
public static final SyncDurationMetrics NO_OP_SYNC_DURATION_METRICS =
|
||||
new SyncDurationMetrics(new NoOpMetricsSystem());
|
||||
|
||||
private final LabelledMetric<OperationTimer> timer;
|
||||
|
||||
private final HashMap<String, OperationTimer.TimingContext> timers = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link SyncDurationMetrics} instance.
|
||||
*
|
||||
* @param metricsSystem The {@link MetricsSystem} to use to record metrics.
|
||||
*/
|
||||
public SyncDurationMetrics(final MetricsSystem metricsSystem) {
|
||||
timer =
|
||||
metricsSystem.createSimpleLabelledTimer(
|
||||
BesuMetricCategory.SYNCHRONIZER, "sync_duration", "Time taken to sync", "name");
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a timer for the given synchronization phase.
|
||||
*
|
||||
* @param label The synchronization phase to start the timer for.
|
||||
*/
|
||||
public void startTimer(final Labels label) {
|
||||
timers.computeIfAbsent(label.name(), k -> timer.labels(label.name()).startTimer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the timer for the given synchronization phase.
|
||||
*
|
||||
* @param label The synchronization phase to stop the timer for.
|
||||
*/
|
||||
public void stopTimer(final Labels label) {
|
||||
OperationTimer.TimingContext context = timers.remove(label.name());
|
||||
if (context != null) {
|
||||
context.stopTimer();
|
||||
}
|
||||
}
|
||||
|
||||
/** Enum representing the different synchronization phases. */
|
||||
public enum Labels {
|
||||
/**
|
||||
* Total time taken to get into sync. It is useful for SNAP and CHECKPOINT sync-modes only.
|
||||
*
|
||||
* <p>Total sync duration includes the separate stages mentioned below, some of which occur in
|
||||
* parallel.
|
||||
*
|
||||
* <p>Total sync duration excludes the backwards sync stage due to implementation challenges.
|
||||
* The backwards sync should be a very short duration following the other sync stages.
|
||||
*/
|
||||
TOTAL_SYNC_DURATION,
|
||||
/** Time taken to download the chain data (headers, blocks, receipts). */
|
||||
CHAIN_DOWNLOAD_DURATION,
|
||||
/** Time taken to download the initial world state, before the healing step. */
|
||||
SNAP_INITIAL_WORLD_STATE_DOWNLOAD_DURATION,
|
||||
/** Time taken to heal the world state, after the initial download. */
|
||||
SNAP_WORLD_STATE_HEALING_DURATION,
|
||||
/** Time taken to do the flat database heal. */
|
||||
FLAT_DB_HEAL;
|
||||
}
|
||||
}
|
||||
@@ -104,6 +104,15 @@ public class NoOpMetricsSystem implements ObservableMetricsSystem {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelledMetric<OperationTimer> createSimpleLabelledTimer(
|
||||
final MetricCategory category,
|
||||
final String name,
|
||||
final String help,
|
||||
final String... labelNames) {
|
||||
return getOperationTimerLabelledMetric(labelNames.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelledMetric<OperationTimer> createLabelledTimer(
|
||||
final MetricCategory category,
|
||||
|
||||
@@ -231,6 +231,15 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelledMetric<OperationTimer> createSimpleLabelledTimer(
|
||||
final MetricCategory category,
|
||||
final String name,
|
||||
final String help,
|
||||
final String... labelNames) {
|
||||
return createLabelledTimer(category, name, help, labelNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelledMetric<OperationTimer> createLabelledTimer(
|
||||
final MetricCategory category,
|
||||
|
||||
@@ -40,6 +40,7 @@ import io.prometheus.client.Collector.MetricFamilySamples;
|
||||
import io.prometheus.client.Collector.MetricFamilySamples.Sample;
|
||||
import io.prometheus.client.CollectorRegistry;
|
||||
import io.prometheus.client.Counter;
|
||||
import io.prometheus.client.Histogram;
|
||||
import io.prometheus.client.Summary;
|
||||
import io.prometheus.client.hotspot.BufferPoolsExports;
|
||||
import io.prometheus.client.hotspot.ClassLoadingExports;
|
||||
@@ -139,6 +140,27 @@ public class PrometheusMetricsSystem implements ObservableMetricsSystem {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelledMetric<OperationTimer> createSimpleLabelledTimer(
|
||||
final MetricCategory category,
|
||||
final String name,
|
||||
final String help,
|
||||
final String... labelNames) {
|
||||
final String metricName = convertToPrometheusName(category, name);
|
||||
return cachedTimers.computeIfAbsent(
|
||||
metricName,
|
||||
(k) -> {
|
||||
if (timersEnabled && isCategoryEnabled(category)) {
|
||||
final Histogram histogram =
|
||||
Histogram.build(metricName, help).labelNames(labelNames).buckets(1D).create();
|
||||
addCollectorUnchecked(category, histogram);
|
||||
return new PrometheusSimpleTimer(histogram);
|
||||
} else {
|
||||
return NoOpMetricsSystem.getOperationTimerLabelledMetric(labelNames.length);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createGauge(
|
||||
final MetricCategory category,
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.metrics.prometheus;
|
||||
|
||||
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
|
||||
import org.hyperledger.besu.plugin.services.metrics.OperationTimer;
|
||||
|
||||
import io.prometheus.client.Histogram;
|
||||
|
||||
class PrometheusSimpleTimer implements LabelledMetric<OperationTimer> {
|
||||
|
||||
private final Histogram histogram;
|
||||
|
||||
public PrometheusSimpleTimer(final Histogram histogram) {
|
||||
this.histogram = histogram;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationTimer labels(final String... labels) {
|
||||
final Histogram.Child metric = histogram.labels(labels);
|
||||
return () -> metric.startTimer()::observeDuration;
|
||||
}
|
||||
}
|
||||
@@ -75,6 +75,15 @@ public class StubMetricsSystem implements ObservableMetricsSystem {
|
||||
return labelValues -> NoOpMetricsSystem.NO_OP_OPERATION_TIMER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelledMetric<OperationTimer> createSimpleLabelledTimer(
|
||||
final MetricCategory category,
|
||||
final String name,
|
||||
final String help,
|
||||
final String... labelNames) {
|
||||
return labelValues -> NoOpMetricsSystem.NO_OP_OPERATION_TIMER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createGauge(
|
||||
final MetricCategory category,
|
||||
|
||||
@@ -70,7 +70,7 @@ Calculated : ${currentHash}
|
||||
tasks.register('checkAPIChanges', FileStateChecker) {
|
||||
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
|
||||
files = sourceSets.main.allJava.files
|
||||
knownHash = '2tFIKwEd8T5I37ywbFnVcMwTR8HiiCC6gO1Chd3hZp8='
|
||||
knownHash = 'V/bdVbzJLjdwch266dHHuxIGwiCRhS4w3jDwHt4TWqg='
|
||||
}
|
||||
check.dependsOn('checkAPIChanges')
|
||||
|
||||
|
||||
@@ -89,6 +89,34 @@ public interface MetricsSystem extends BesuService {
|
||||
LabelledMetric<OperationTimer> createLabelledTimer(
|
||||
MetricCategory category, String name, String help, String... labelNames);
|
||||
|
||||
/**
|
||||
* Creates a simple Timer.
|
||||
*
|
||||
* @param category The {@link MetricCategory} this timer is assigned to.
|
||||
* @param name A name for this metric.
|
||||
* @param help A human readable description of the metric.
|
||||
* @return The created Timer instance.
|
||||
*/
|
||||
default OperationTimer createSimpleTimer(
|
||||
final MetricCategory category, final String name, final String help) {
|
||||
return createSimpleLabelledTimer(category, name, help).labels();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a simple Timer with assigned labels.
|
||||
*
|
||||
* @param category The {@link MetricCategory} this timer is assigned to.
|
||||
* @param name A name for this metric.
|
||||
* @param help A human readable description of the metric.
|
||||
* @param labelNames An array of labels to assign to the Timer.
|
||||
* @return The created Timer instance.
|
||||
*/
|
||||
LabelledMetric<OperationTimer> createSimpleLabelledTimer(
|
||||
final MetricCategory category,
|
||||
final String name,
|
||||
final String help,
|
||||
final String... labelNames);
|
||||
|
||||
/**
|
||||
* Creates a gauge for displaying double vales. A gauge is a metric to report the current value.
|
||||
* The metric value may go up or down.
|
||||
|
||||
@@ -39,6 +39,7 @@ dependencies {
|
||||
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind'
|
||||
implementation 'com.gitlab.javafuzz:core'
|
||||
implementation 'com.google.guava:guava'
|
||||
implementation 'info.picocli:picocli'
|
||||
implementation 'io.tmio:tuweni-bytes'
|
||||
implementation 'org.jacoco:org.jacoco.agent'
|
||||
@@ -56,6 +57,7 @@ application {
|
||||
def corpusDir = "${buildDir}/generated/corpus"
|
||||
|
||||
tasks.register("runFuzzer", JavaExec) {
|
||||
doNotTrackState("Produces no artifacts")
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
mainClass = 'org.hyperledger.besu.testfuzz.BesuFuzz'
|
||||
|
||||
@@ -69,6 +71,15 @@ tasks.register("runFuzzer", JavaExec) {
|
||||
}
|
||||
}
|
||||
|
||||
// This fuzzes besu as an external client. Besu fuzzing as a local client is enabled by default.
|
||||
tasks.register("fuzzBesu") {
|
||||
dependsOn(":installDist")
|
||||
doLast {
|
||||
runFuzzer.args += "--client=besu=../build/install/besu/bin/evmtool code-validate"
|
||||
}
|
||||
finalizedBy("runFuzzer")
|
||||
}
|
||||
|
||||
tasks.register("fuzzEvmone") {
|
||||
doLast {
|
||||
runFuzzer.args += "--client=evm1=evmone-eofparse"
|
||||
|
||||
@@ -17,14 +17,10 @@ package org.hyperledger.besu.testfuzz;
|
||||
import static org.hyperledger.besu.testfuzz.EofContainerSubCommand.COMMAND_NAME;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.ethereum.referencetests.EOFTestCaseSpec;
|
||||
import org.hyperledger.besu.evm.Code;
|
||||
import org.hyperledger.besu.evm.EVM;
|
||||
import org.hyperledger.besu.evm.MainnetEVMs;
|
||||
import org.hyperledger.besu.evm.code.CodeInvalid;
|
||||
import org.hyperledger.besu.evm.code.CodeV1;
|
||||
import org.hyperledger.besu.evm.code.EOFLayout;
|
||||
import org.hyperledger.besu.evm.code.EOFLayout.EOFContainerMode;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
@@ -39,6 +35,9 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser.Feature;
|
||||
import com.fasterxml.jackson.core.util.DefaultIndenter;
|
||||
@@ -50,6 +49,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.gitlab.javafuzz.core.AbstractFuzzTarget;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import picocli.CommandLine;
|
||||
import picocli.CommandLine.Option;
|
||||
@@ -83,6 +83,23 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab
|
||||
description = "Add a client for differential fuzzing")
|
||||
private final Map<String, String> clients = new LinkedHashMap<>();
|
||||
|
||||
@Option(
|
||||
names = {"--no-local-client"},
|
||||
description = "Don't include built-in Besu with fuzzing")
|
||||
private final Boolean noLocalClient = false;
|
||||
|
||||
@Option(
|
||||
names = {"--time-limit-ns"},
|
||||
defaultValue = "5000",
|
||||
description = "Time threshold, in nanoseconds, that results in a fuzz error if exceeded")
|
||||
private long timeThresholdMicros = 5_000;
|
||||
|
||||
@Option(
|
||||
names = {"--time-limit-warmup"},
|
||||
defaultValue = "2000",
|
||||
description = "Minimum number of fuzz tests before a time limit fuzz error can occur")
|
||||
private long timeThresholdIterations = 2_000;
|
||||
|
||||
@CommandLine.ParentCommand private final BesuFuzzCommand parentCommand;
|
||||
|
||||
static final ObjectMapper eofTestMapper = createObjectMapper();
|
||||
@@ -91,7 +108,7 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab
|
||||
.getTypeFactory()
|
||||
.constructParametricType(Map.class, String.class, EOFTestCaseSpec.class);
|
||||
|
||||
List<ExternalClient> externalClients = new ArrayList<>();
|
||||
List<FuzzingClient> fuzzingClients = new ArrayList<>();
|
||||
EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT);
|
||||
long validContainers;
|
||||
long totalContainers;
|
||||
@@ -150,7 +167,10 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab
|
||||
}
|
||||
}
|
||||
|
||||
clients.forEach((k, v) -> externalClients.add(new StreamingClient(k, v.split(" "))));
|
||||
if (!noLocalClient) {
|
||||
fuzzingClients.add(new InternalClient("this"));
|
||||
}
|
||||
clients.forEach((k, v) -> fuzzingClients.add(new StreamingClient(k, v.split(" "))));
|
||||
System.out.println("Fuzzing client set: " + clients.keySet());
|
||||
|
||||
try {
|
||||
@@ -196,55 +216,54 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab
|
||||
public void fuzz(final byte[] bytes) {
|
||||
Bytes eofUnderTest = Bytes.wrap(bytes);
|
||||
String eofUnderTestHexString = eofUnderTest.toHexString();
|
||||
Code code = evm.getCodeUncached(eofUnderTest);
|
||||
Map<String, String> results = new LinkedHashMap<>();
|
||||
boolean mismatch = false;
|
||||
for (var client : externalClients) {
|
||||
String value = client.differentialFuzz(eofUnderTestHexString);
|
||||
results.put(client.getName(), value);
|
||||
if (value == null || value.startsWith("fail: ")) {
|
||||
mismatch = true; // if an external client fails, always report it as an error
|
||||
}
|
||||
}
|
||||
boolean besuValid = false;
|
||||
String besuReason;
|
||||
if (!code.isValid()) {
|
||||
besuReason = ((CodeInvalid) code).getInvalidReason();
|
||||
} else if (code.getEofVersion() != 1) {
|
||||
EOFLayout layout = EOFLayout.parseEOF(eofUnderTest);
|
||||
if (layout.isValid()) {
|
||||
besuReason = "Besu Parsing Error";
|
||||
parentCommand.out.println(layout.version());
|
||||
parentCommand.out.println(layout.invalidReason());
|
||||
parentCommand.out.println(code.getEofVersion());
|
||||
parentCommand.out.println(code.getClass().getName());
|
||||
System.exit(1);
|
||||
mismatch = true;
|
||||
} else {
|
||||
besuReason = layout.invalidReason();
|
||||
}
|
||||
} else if (EOFContainerMode.INITCODE.equals(
|
||||
((CodeV1) code).getEofLayout().containerMode().get())) {
|
||||
besuReason = "Code is initcode, not runtime";
|
||||
} else {
|
||||
besuReason = "OK";
|
||||
besuValid = true;
|
||||
}
|
||||
for (var entry : results.entrySet()) {
|
||||
mismatch =
|
||||
mismatch
|
||||
|| besuValid != entry.getValue().toUpperCase(Locale.getDefault()).startsWith("OK");
|
||||
}
|
||||
if (mismatch) {
|
||||
parentCommand.out.println("besu: " + besuReason);
|
||||
for (var entry : results.entrySet()) {
|
||||
|
||||
AtomicBoolean passHappened = new AtomicBoolean(false);
|
||||
AtomicBoolean failHappened = new AtomicBoolean(false);
|
||||
|
||||
Map<String, String> resultMap =
|
||||
fuzzingClients.stream()
|
||||
.parallel()
|
||||
.map(
|
||||
client -> {
|
||||
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||
String value = client.differentialFuzz(eofUnderTestHexString);
|
||||
stopwatch.stop();
|
||||
long elapsedMicros = stopwatch.elapsed(TimeUnit.MICROSECONDS);
|
||||
if (elapsedMicros > timeThresholdMicros
|
||||
&& totalContainers > timeThresholdIterations) {
|
||||
Hash name = Hash.hash(eofUnderTest);
|
||||
parentCommand.out.printf(
|
||||
"%s: slow validation %d µs%n", client.getName(), elapsedMicros);
|
||||
try {
|
||||
Files.writeString(
|
||||
Path.of("slow-" + client.getName() + "-" + name + ".hex"),
|
||||
eofUnderTestHexString);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (value.toLowerCase(Locale.ROOT).startsWith("ok")) {
|
||||
passHappened.set(true);
|
||||
} else if (value.toLowerCase(Locale.ROOT).startsWith("err")) {
|
||||
failHappened.set(true);
|
||||
} else {
|
||||
// unexpected output: trigger a mismatch
|
||||
passHappened.set(true);
|
||||
failHappened.set(true);
|
||||
}
|
||||
return Map.entry(client.getName(), value);
|
||||
})
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
|
||||
if (passHappened.get() && failHappened.get()) {
|
||||
for (var entry : resultMap.entrySet()) {
|
||||
parentCommand.out.println(entry.getKey() + ": " + entry.getValue());
|
||||
}
|
||||
parentCommand.out.println("code: " + eofUnderTest.toUnprefixedHexString());
|
||||
parentCommand.out.println("size: " + eofUnderTest.size());
|
||||
parentCommand.out.println();
|
||||
} else {
|
||||
if (besuValid) {
|
||||
if (passHappened.get()) {
|
||||
validContainers++;
|
||||
}
|
||||
totalContainers++;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.testfuzz;
|
||||
|
||||
interface ExternalClient {
|
||||
interface FuzzingClient {
|
||||
|
||||
String getName();
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.testfuzz;
|
||||
|
||||
import org.hyperledger.besu.evm.Code;
|
||||
import org.hyperledger.besu.evm.EVM;
|
||||
import org.hyperledger.besu.evm.MainnetEVMs;
|
||||
import org.hyperledger.besu.evm.code.CodeInvalid;
|
||||
import org.hyperledger.besu.evm.code.CodeV1;
|
||||
import org.hyperledger.besu.evm.code.EOFLayout;
|
||||
import org.hyperledger.besu.evm.code.EOFLayout.EOFContainerMode;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
class InternalClient implements FuzzingClient {
|
||||
String name;
|
||||
final EVM evm;
|
||||
|
||||
public InternalClient(final String clientName) {
|
||||
this.name = clientName;
|
||||
this.evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("java:S2142")
|
||||
public String differentialFuzz(final String data) {
|
||||
try {
|
||||
Bytes clientData = Bytes.fromHexString(data);
|
||||
Code code = evm.getCodeUncached(clientData);
|
||||
if (code.getEofVersion() < 1) {
|
||||
return "err: legacy EVM";
|
||||
} else if (!code.isValid()) {
|
||||
return "err: " + ((CodeInvalid) code).getInvalidReason();
|
||||
} else {
|
||||
EOFLayout layout = ((CodeV1) code).getEofLayout();
|
||||
if (EOFContainerMode.INITCODE.equals(layout.containerMode().get())) {
|
||||
return "err: initcode container when runtime mode expected";
|
||||
}
|
||||
return "OK %d/%d/%d"
|
||||
.formatted(
|
||||
layout.getCodeSectionCount(), layout.getSubcontainerCount(), layout.dataLength());
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
return "fail: " + e.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@SuppressWarnings({"java:S106", "CallToPrintStackTrace"}) // we use lots the console, on purpose
|
||||
class SingleQueryClient implements ExternalClient {
|
||||
class SingleQueryClient implements FuzzingClient {
|
||||
final String name;
|
||||
String[] command;
|
||||
Pattern okRegexp;
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
class StreamingClient implements ExternalClient {
|
||||
class StreamingClient implements FuzzingClient {
|
||||
final String name;
|
||||
final BufferedReader reader;
|
||||
final PrintWriter writer;
|
||||
|
||||
Reference in New Issue
Block a user