Merge branch 'main' into 7311-add-GetHeadersFromPeerTask

pull/7781/head
Matilda-Clerke 4 days ago committed by GitHub
commit 48e40c0fad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      CHANGELOG.md
  2. 1
      MAINTAINERS.md
  3. 2
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.java
  4. 10
      besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java
  5. 133
      besu/src/main/java/org/hyperledger/besu/cli/options/RpcWebsocketOptions.java
  6. 28
      besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java
  7. 4
      besu/src/main/scripts/unixStartScript.txt
  8. 12
      besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
  9. 24
      besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java
  10. 13
      besu/src/test/resources/everything_config.toml
  11. 2
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java
  12. 2
      docs/trace_rpc_apis.md
  13. 112
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketConfiguration.java
  14. 60
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketService.java
  15. 444
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceTLSTest.java
  16. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java
  17. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ProtocolContext.java
  18. 15
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java
  19. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/forest/ForestWorldStateArchive.java
  20. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/WorldStateArchive.java
  21. 1
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java
  22. 5
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java
  23. 39
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/WorldStateHealerHelper.java
  24. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java
  25. 4
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java
  26. 22
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProviderTest.java
  27. 7
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java
  28. 6
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java
  29. 8
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionBroadcaster.java
  30. 1
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
  31. 5
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerGetAccountRangeTest.java
  32. 297
      gradle/verification-metadata.xml
  33. 3
      metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImpl.java
  34. 2
      platform/build.gradle
  35. 2
      plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorageTest.java
  36. 2
      testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/FuzzTarget.java

@ -10,6 +10,7 @@
### Additions and Improvements
- Fine tune already seen txs tracker when a tx is removed from the pool [#7755](https://github.com/hyperledger/besu/pull/7755)
- Support for enabling and configuring TLS/mTLS in WebSocket service. [#7854](https://github.com/hyperledger/besu/pull/7854)
- Create and publish Besu BOM (Bill of Materials) [#7615](https://github.com/hyperledger/besu/pull/7615)
- Update Java dependencies [#7786](https://github.com/hyperledger/besu/pull/7786)
- Add a method to get all the transaction in the pool, to the `TransactionPoolService`, to easily access the transaction pool content from plugins [#7813](https://github.com/hyperledger/besu/pull/7813)
@ -17,6 +18,7 @@
### Bug fixes
- Fix registering new metric categories from plugins [#7825](https://github.com/hyperledger/besu/pull/7825)
- Fix CVE-2024-47535 [7878](https://github.com/hyperledger/besu/pull/7878)
## 24.10.0
@ -102,6 +104,7 @@ This release version has been deprecated release due to CI bug
- Remove long-deprecated `perm*whitelist*` methods [#7401](https://github.com/hyperledger/besu/pull/7401)
### Additions and Improvements
- Allow optional loading of `jemalloc` (if installed) by setting the environment variable `BESU_USING_JEMALLOC` to true/false. It that env is not set at all it will behave as if it is set to `true`
- Expose set finalized/safe block in plugin api BlockchainService. These method can be used by plugins to set finalized/safe block for a PoA network (such as QBFT, IBFT and Clique).[#7382](https://github.com/hyperledger/besu/pull/7382)
- 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)

@ -22,6 +22,7 @@
| Luis Pinto | lu-pinto | lu-pinto |
| Lucas Saldanha | lucassaldanha | lucassaldanha |
| Sally MacFarlane | macfarla | macfarla |
| Matilda Clerke | Matilda-Clerke | MatildaClerke |
| Karim Taam | matkt | matkt |
| Matthew Whitehead| matthew1001 | matthew.whitehead |
| Meredith Baxter | mbaxter | mbaxter |

@ -51,7 +51,7 @@ public class TestMetricsPlugin implements BesuPlugin {
.createGauge(
TestMetricCategory.TEST_METRIC_CATEGORY,
"test_metric",
"Returns 1 on succes",
"Returns 1 on success",
() -> 1.0);
}

@ -433,14 +433,18 @@ public class ConfigurationOverviewBuilder {
private void detectJemalloc(final List<String> lines) {
Optional.ofNullable(Objects.isNull(environment) ? null : environment.get("BESU_USING_JEMALLOC"))
.ifPresentOrElse(
t -> {
jemallocEnabled -> {
try {
if (Boolean.parseBoolean(jemallocEnabled)) {
final String version = PlatformDetector.getJemalloc();
lines.add("jemalloc: " + version);
} else {
logger.warn(
"besu_using_jemalloc is present but is not set to true, jemalloc library not loaded");
}
} catch (final Throwable throwable) {
logger.warn(
"BESU_USING_JEMALLOC is present but we failed to load jemalloc library to get the version",
throwable);
"besu_using_jemalloc is present but we failed to load jemalloc library to get the version");
}
},
() -> {

@ -120,6 +120,71 @@ public class RpcWebsocketOptions {
arity = "1")
private final File rpcWsAuthenticationPublicKeyFile = null;
@CommandLine.Option(
names = {"--rpc-ws-ssl-enabled"},
description = "Enable SSL/TLS for the WebSocket RPC service")
private final Boolean isRpcWsSslEnabled = false;
@CommandLine.Option(
names = {"--rpc-ws-ssl-keystore-file"},
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
description = "Path to the keystore file for the WebSocket RPC service")
private String rpcWsKeyStoreFile = null;
@CommandLine.Option(
names = {"--rpc-ws-ssl-keystore-password"},
paramLabel = "<PASSWORD>",
description = "Password for the WebSocket RPC keystore file")
private String rpcWsKeyStorePassword = null;
@CommandLine.Option(
names = {"--rpc-ws-ssl-key-file"},
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
description = "Path to the PEM key file for the WebSocket RPC service")
private String rpcWsKeyFile = null;
@CommandLine.Option(
names = {"--rpc-ws-ssl-cert-file"},
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
description = "Path to the PEM cert file for the WebSocket RPC service")
private String rpcWsCertFile = null;
@CommandLine.Option(
names = {"--rpc-ws-ssl-keystore-type"},
paramLabel = "<TYPE>",
description = "Type of the WebSocket RPC keystore (JKS, PKCS12, PEM)")
private String rpcWsKeyStoreType = null;
// For client authentication (mTLS)
@CommandLine.Option(
names = {"--rpc-ws-ssl-client-auth-enabled"},
description = "Enable client authentication for the WebSocket RPC service")
private final Boolean isRpcWsClientAuthEnabled = false;
@CommandLine.Option(
names = {"--rpc-ws-ssl-truststore-file"},
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
description = "Path to the truststore file for the WebSocket RPC service")
private String rpcWsTrustStoreFile = null;
@CommandLine.Option(
names = {"--rpc-ws-ssl-truststore-password"},
paramLabel = "<PASSWORD>",
description = "Password for the WebSocket RPC truststore file")
private String rpcWsTrustStorePassword = null;
@CommandLine.Option(
names = {"--rpc-ws-ssl-trustcert-file"},
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
description = "Path to the PEM trustcert file for the WebSocket RPC service")
private String rpcWsTrustCertFile = null;
@CommandLine.Option(
names = {"--rpc-ws-ssl-truststore-type"},
paramLabel = "<TYPE>",
description = "Type of the truststore (JKS, PKCS12, PEM)")
private String rpcWsTrustStoreType = null;
/** Default Constructor. */
public RpcWebsocketOptions() {}
@ -184,7 +249,61 @@ public class RpcWebsocketOptions {
"--rpc-ws-authentication-enabled",
"--rpc-ws-authentication-credentials-file",
"--rpc-ws-authentication-public-key-file",
"--rpc-ws-authentication-jwt-algorithm"));
"--rpc-ws-authentication-jwt-algorithm",
"--rpc-ws-ssl-enabled"));
CommandLineUtils.checkOptionDependencies(
logger,
commandLine,
"--rpc-ws-ssl-enabled",
!isRpcWsSslEnabled,
List.of(
"--rpc-ws-ssl-keystore-file",
"--rpc-ws-ssl-keystore-type",
"--rpc-ws-ssl-client-auth-enabled"));
CommandLineUtils.checkOptionDependencies(
logger,
commandLine,
"--rpc-ws-ssl-client-auth-enabled",
!isRpcWsClientAuthEnabled,
List.of(
"--rpc-ws-ssl-truststore-file",
"--rpc-ws-ssl-truststore-type",
"--rpc-ws-ssl-trustcert-file"));
if (isRpcWsSslEnabled) {
if ("PEM".equalsIgnoreCase(rpcWsKeyStoreType)) {
CommandLineUtils.checkOptionDependencies(
logger,
commandLine,
"--rpc-ws-ssl-key-file",
rpcWsKeyFile == null,
List.of("--rpc-ws-ssl-cert-file"));
CommandLineUtils.checkOptionDependencies(
logger,
commandLine,
"--rpc-ws-ssl-cert-file",
rpcWsCertFile == null,
List.of("--rpc-ws-ssl-key-file"));
} else {
CommandLineUtils.checkOptionDependencies(
logger,
commandLine,
"--rpc-ws-ssl-keystore-file",
rpcWsKeyStoreFile == null,
List.of("--rpc-ws-ssl-keystore-password"));
}
}
if (isRpcWsClientAuthEnabled && !"PEM".equalsIgnoreCase(rpcWsTrustStoreType)) {
CommandLineUtils.checkOptionDependencies(
logger,
commandLine,
"--rpc-ws-ssl-truststore-file",
rpcWsTrustStoreFile == null,
List.of("--rpc-ws-ssl-truststore-password"));
}
if (isRpcWsAuthenticationEnabled) {
CommandLineUtils.checkOptionDependencies(
@ -222,6 +341,18 @@ public class RpcWebsocketOptions {
webSocketConfiguration.setAuthenticationPublicKeyFile(rpcWsAuthenticationPublicKeyFile);
webSocketConfiguration.setAuthenticationAlgorithm(rpcWebsocketsAuthenticationAlgorithm);
webSocketConfiguration.setTimeoutSec(wsTimoutSec);
webSocketConfiguration.setSslEnabled(isRpcWsSslEnabled);
webSocketConfiguration.setKeyStorePath(rpcWsKeyStoreFile);
webSocketConfiguration.setKeyStorePassword(rpcWsKeyStorePassword);
webSocketConfiguration.setKeyStoreType(rpcWsKeyStoreType);
webSocketConfiguration.setClientAuthEnabled(isRpcWsClientAuthEnabled);
webSocketConfiguration.setTrustStorePath(rpcWsTrustStoreFile);
webSocketConfiguration.setTrustStorePassword(rpcWsTrustStorePassword);
webSocketConfiguration.setTrustStoreType(rpcWsTrustStoreType);
webSocketConfiguration.setKeyPath(rpcWsKeyFile);
webSocketConfiguration.setCertPath(rpcWsCertFile);
webSocketConfiguration.setTrustCertPath(rpcWsTrustCertFile);
return webSocketConfiguration;
}

@ -45,6 +45,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.eth.EthProtocol;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.hyperledger.besu.ethereum.eth.SnapProtocol;
@ -93,6 +94,7 @@ import org.hyperledger.besu.ethereum.trie.forest.ForestWorldStateArchive;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive.WorldStateHealer;
import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage;
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
@ -113,6 +115,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import org.slf4j.Logger;
@ -589,9 +592,14 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
.map(BesuComponent::getCachedMerkleTrieLoader)
.orElseGet(() -> new BonsaiCachedMerkleTrieLoader(metricsSystem));
final var worldStateHealerSupplier = new AtomicReference<WorldStateHealer>();
final WorldStateArchive worldStateArchive =
createWorldStateArchive(
worldStateStorageCoordinator, blockchain, bonsaiCachedMerkleTrieLoader);
worldStateStorageCoordinator,
blockchain,
bonsaiCachedMerkleTrieLoader,
worldStateHealerSupplier::get);
if (maybeStoredGenesisBlockHash.isEmpty()) {
genesisState.writeStateTo(worldStateArchive.getMutable());
@ -720,6 +728,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
ethProtocolManager,
pivotBlockSelector);
worldStateHealerSupplier.set(synchronizer::healWorldState);
ethPeers.setTrailingPeerRequirementsSupplier(synchronizer::calculateTrailingPeerRequirements);
if (syncConfig.getSyncMode() == SyncMode.SNAP
@ -730,11 +740,9 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
ethPeers.snapServerPeersNeeded(false);
}
protocolContext.setSynchronizer(synchronizer);
final Optional<SnapProtocolManager> maybeSnapProtocolManager =
createSnapProtocolManager(
protocolContext, worldStateStorageCoordinator, ethPeers, snapMessages);
protocolContext, worldStateStorageCoordinator, ethPeers, snapMessages, synchronizer);
final MiningCoordinator miningCoordinator =
createMiningCoordinator(
@ -1101,20 +1109,23 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
final ProtocolContext protocolContext,
final WorldStateStorageCoordinator worldStateStorageCoordinator,
final EthPeers ethPeers,
final EthMessages snapMessages) {
final EthMessages snapMessages,
final Synchronizer synchronizer) {
return Optional.of(
new SnapProtocolManager(
worldStateStorageCoordinator,
syncConfig.getSnapSyncConfiguration(),
ethPeers,
snapMessages,
protocolContext));
protocolContext,
synchronizer));
}
WorldStateArchive createWorldStateArchive(
final WorldStateStorageCoordinator worldStateStorageCoordinator,
final Blockchain blockchain,
final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader) {
final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader,
final Supplier<WorldStateHealer> worldStateHealerSupplier) {
return switch (dataStorageConfiguration.getDataStorageFormat()) {
case BONSAI -> {
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage =
@ -1129,7 +1140,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
.getMaxLayersToLoad()),
bonsaiCachedMerkleTrieLoader,
besuComponent.map(BesuComponent::getBesuPluginContext).orElse(null),
evmConfiguration);
evmConfiguration,
worldStateHealerSupplier);
}
case FOREST -> {
final WorldStatePreimageStorage preimageStorage =

@ -182,19 +182,19 @@ APP_ARGS=`save "\$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- \$DEFAULT_JVM_OPTS \$JAVA_OPTS \$${optsEnvironmentVar} <% if ( appNameSystemProperty ) { %>"\"-D${appNameSystemProperty}=\$APP_BASE_NAME\"" <% } %>-classpath "\"\$CLASSPATH\"" <% if ( mainClassName.startsWith('--module ') ) { %>--module-path "\"\$MODULE_PATH\"" <% } %>${mainClassName} "\$APP_ARGS"
unset BESU_USING_JEMALLOC
if [ "\$darwin" = "false" -a "\$msys" = "false" ]; then
if [ "\$BESU_USING_JEMALLOC" != "FALSE" -a "\$BESU_USING_JEMALLOC" != "false" ]; then
# check if jemalloc is available
TEST_JEMALLOC=\$(LD_PRELOAD=libjemalloc.so sh -c true 2>&1)
# if jemalloc is available the output is empty, otherwise the output has an error line
if [ -z "\$TEST_JEMALLOC" ]; then
export LD_PRELOAD=libjemalloc.so
export BESU_USING_JEMALLOC=true
else
# jemalloc not available, as fallback limit malloc to 2 arenas
export MALLOC_ARENA_MAX=2
fi
fi
fi
exec "\$JAVACMD" "\$@"

@ -37,6 +37,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNotNull;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@ -2412,13 +2413,16 @@ public class BesuCommandTest extends CommandTestAbstract {
@Test
public void logsWarningWhenFailToLoadJemalloc() {
assumeTrue(PlatformDetector.getOSType().equals("linux"));
setEnvironmentVariable("BESU_USING_JEMALLOC", "true");
setEnvironmentVariable("BESU_USING_JEMALLOC", "false");
parseCommand();
verify(mockLogger)
.warn(
eq(
"BESU_USING_JEMALLOC is present but we failed to load jemalloc library to get the version"),
any(Throwable.class));
argThat(
arg ->
arg.equals(
"besu_using_jemalloc is present but is not set to true, jemalloc library not loaded")
|| arg.equals(
"besu_using_jemalloc is present but we failed to load jemalloc library to get the version")));
}
@Test

@ -14,12 +14,18 @@
*/
package org.hyperledger.besu.cli.options;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.metrics.BesuMetricCategory;
import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl;
import org.hyperledger.besu.metrics.StandardMetricCategory;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import java.util.EnumSet;
import java.util.stream.Collectors;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@ -64,4 +70,22 @@ public class MetricsOptionsTest
protected String[] getNonOptionFields() {
return new String[] {"metricCategoryRegistry"};
}
@Test
public void enableRocksDbCategories() {
final var rocksDbMetricsCategories =
EnumSet.of(
BesuMetricCategory.KVSTORE_ROCKSDB,
BesuMetricCategory.KVSTORE_ROCKSDB_STATS,
BesuMetricCategory.KVSTORE_PRIVATE_ROCKSDB,
BesuMetricCategory.KVSTORE_PRIVATE_ROCKSDB_STATS);
internalTestSuccess(
metricsConfBuilder -> {
assertThat(metricsConfBuilder.build().getMetricCategories())
.containsExactlyInAnyOrderElementsOf(rocksDbMetricsCategories);
},
"--metrics-categories",
rocksDbMetricsCategories.stream().map(Enum::name).collect(Collectors.joining(",")));
}
}

@ -120,6 +120,19 @@ rpc-ws-max-frame-size=65535
rpc-ws-authentication-enabled=false
rpc-ws-authentication-credentials-file="none"
rpc-ws-authentication-jwt-public-key-file="none"
rpc-ws-ssl-enabled=false
rpc-ws-ssl-keystore-file="none.pfx"
rpc-ws-ssl-keystore-password="none.passwd"
rpc-ws-ssl-keystore-type="none"
rpc-ws-ssl-client-auth-enabled=false
rpc-ws-ssl-truststore-file="none.pfx"
rpc-ws-ssl-truststore-password="none.passwd"
rpc-ws-ssl-truststore-type="none"
rpc-ws-ssl-key-file="none.pfx"
rpc-ws-ssl-cert-file="none.pfx"
rpc-ws-ssl-trustcert-file="none.pfx"
# API
api-gas-price-blocks=100

@ -59,7 +59,6 @@ import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration;
import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration.MutableInitValues;
import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration.Unstable;
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
@ -190,7 +189,6 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
protocolContext =
new ProtocolContext(blockchain, worldStateArchive, mergeContext, badBlockManager);
protocolContext.setSynchronizer(mock(Synchronizer.class));
var mutable = worldStateArchive.getMutable();
genesisState.writeStateTo(mutable);
mutable.persist(null);

@ -16,7 +16,7 @@ implementations of Besu might track gas refunds separately.
### Returned Memory from Calls
In the `vmTrace` `ope.ex.mem` fields Besu only reports actual data returned
In the `vmTrace` `op.ex.mem` fields Besu only reports actual data returned
from a `RETURN` opcode. Other implementations return the contents of the
reserved output space for the call operations. Note two major differences:

@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import com.google.common.base.MoreObjects;
@ -49,6 +50,21 @@ public class WebSocketConfiguration {
private int maxActiveConnections;
private int maxFrameSize;
private boolean isSslEnabled = false;
private Optional<String> keyStorePath = Optional.empty();
private Optional<String> keyStorePassword = Optional.empty();
private Optional<String> keyStoreType = Optional.of("JKS"); // Default to JKS
private boolean clientAuthEnabled = false;
private Optional<String> trustStorePath = Optional.empty();
private Optional<String> trustStorePassword = Optional.empty();
private Optional<String> trustStoreType = Optional.of("JKS"); // Default to JKS
// For PEM format
private Optional<String> keyPath = Optional.empty();
private Optional<String> certPath = Optional.empty();
private Optional<String> trustCertPath = Optional.empty();
public static WebSocketConfiguration createDefault() {
final WebSocketConfiguration config = new WebSocketConfiguration();
config.setEnabled(false);
@ -159,6 +175,102 @@ public class WebSocketConfiguration {
this.timeoutSec = timeoutSec;
}
public boolean isSslEnabled() {
return isSslEnabled;
}
public void setSslEnabled(final boolean isSslEnabled) {
this.isSslEnabled = isSslEnabled;
}
public Optional<String> getKeyStorePath() {
return keyStorePath;
}
public void setKeyStorePath(final String keyStorePath) {
this.keyStorePath = Optional.ofNullable(keyStorePath);
}
public Optional<String> getKeyStorePassword() {
return keyStorePassword;
}
public void setKeyStorePassword(final String keyStorePassword) {
this.keyStorePassword = Optional.ofNullable(keyStorePassword);
}
// Keystore Type
public Optional<String> getKeyStoreType() {
return keyStoreType;
}
public void setKeyStoreType(final String keyStoreType) {
this.keyStoreType = Optional.ofNullable(keyStoreType);
}
// Key Path (for PEM)
public Optional<String> getKeyPath() {
return keyPath;
}
public void setKeyPath(final String keyPath) {
this.keyPath = Optional.ofNullable(keyPath);
}
// Cert Path (for PEM)
public Optional<String> getCertPath() {
return certPath;
}
public void setCertPath(final String certPath) {
this.certPath = Optional.ofNullable(certPath);
}
// Client Authentication Enabled
public boolean isClientAuthEnabled() {
return clientAuthEnabled;
}
public void setClientAuthEnabled(final boolean clientAuthEnabled) {
this.clientAuthEnabled = clientAuthEnabled;
}
// Truststore Path
public Optional<String> getTrustStorePath() {
return trustStorePath;
}
public void setTrustStorePath(final String trustStorePath) {
this.trustStorePath = Optional.ofNullable(trustStorePath);
}
// Truststore Password
public Optional<String> getTrustStorePassword() {
return trustStorePassword;
}
public void setTrustStorePassword(final String trustStorePassword) {
this.trustStorePassword = Optional.ofNullable(trustStorePassword);
}
// Truststore Type
public Optional<String> getTrustStoreType() {
return trustStoreType;
}
public void setTrustStoreType(final String trustStoreType) {
this.trustStoreType = Optional.ofNullable(trustStoreType);
}
// Trust Cert Path (for PEM)
public Optional<String> getTrustCertPath() {
return trustCertPath;
}
public void setTrustCertPath(final String trustCertPath) {
this.trustCertPath = Optional.ofNullable(trustCertPath);
}
@Override
public boolean equals(final Object o) {
if (this == o) {

@ -25,6 +25,7 @@ import org.hyperledger.besu.metrics.BesuMetricCategory;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.net.InetSocketAddress;
import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
@ -34,6 +35,7 @@ import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.ClientAuth;
import io.vertx.core.http.HttpConnection;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
@ -41,6 +43,9 @@ import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.http.ServerWebSocket;
import io.vertx.core.net.HostAndPort;
import io.vertx.core.net.JksOptions;
import io.vertx.core.net.PemKeyCertOptions;
import io.vertx.core.net.PemTrustOptions;
import io.vertx.core.net.SocketAddress;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
@ -103,9 +108,7 @@ public class WebSocketService {
"Starting Websocket service on {}:{}", configuration.getHost(), configuration.getPort());
final CompletableFuture<?> resultFuture = new CompletableFuture<>();
httpServer =
vertx
.createHttpServer(
HttpServerOptions serverOptions =
new HttpServerOptions()
.setHost(configuration.getHost())
.setPort(configuration.getPort())
@ -114,7 +117,56 @@ public class WebSocketService {
.addWebSocketSubProtocol("undefined")
.setMaxWebSocketFrameSize(configuration.getMaxFrameSize())
.setMaxWebSocketMessageSize(configuration.getMaxFrameSize() * 4)
.setRegisterWebSocketWriteHandlers(true))
.setRegisterWebSocketWriteHandlers(true);
// Check if SSL/TLS is enabled in the configuration
if (configuration.isSslEnabled()) {
serverOptions.setSsl(true);
String keystorePath = configuration.getKeyStorePath().orElse(null);
String keystorePassword = configuration.getKeyStorePassword().orElse(null);
String keyPath = configuration.getKeyPath().orElse(null);
String certPath = configuration.getCertPath().orElse(null);
String keystoreType = configuration.getKeyStoreType().orElse("JKS");
switch (keystoreType.toUpperCase(Locale.getDefault())) {
case "PEM":
serverOptions.setKeyCertOptions(
new PemKeyCertOptions().setKeyPath(keyPath).setCertPath(certPath));
break;
case "JKS":
default:
serverOptions.setKeyCertOptions(
new JksOptions().setPath(keystorePath).setPassword(keystorePassword));
break;
}
}
// Set up truststore for client authentication (mTLS)
if (configuration.isClientAuthEnabled()) {
serverOptions.setClientAuth(ClientAuth.REQUIRED);
String truststorePath = configuration.getTrustStorePath().orElse(null);
String truststorePassword = configuration.getTrustStorePassword().orElse("");
String truststoreType = configuration.getTrustStoreType().orElse("JKS");
String trustCertPath = configuration.getTrustCertPath().orElse(null);
switch (truststoreType.toUpperCase(Locale.getDefault())) {
case "PEM":
serverOptions.setTrustOptions(new PemTrustOptions().addCertPath(trustCertPath));
break;
case "JKS":
default:
serverOptions.setTrustOptions(
new JksOptions().setPath(truststorePath).setPassword(truststorePassword));
break;
}
}
httpServer =
vertx
.createHttpServer(serverOptions)
.webSocketHandler(websocketHandler())
.connectionHandler(connectionHandler())
.requestHandler(httpHandler())

@ -0,0 +1,444 @@
/*
* Copyright contributors to Besu.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.websocket;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import org.hyperledger.besu.ethereum.api.handlers.TimeoutOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.execution.BaseJsonRpcProcessor;
import org.hyperledger.besu.ethereum.api.jsonrpc.execution.JsonRpcExecutor;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.methods.WebSocketMethodsFactory;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.subscription.SubscriptionManager;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.io.File;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.vertx.core.Vertx;
import io.vertx.core.http.WebSocketClient;
import io.vertx.core.http.WebSocketClientOptions;
import io.vertx.core.net.JksOptions;
import io.vertx.core.net.PemTrustOptions;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(VertxExtension.class)
public class WebSocketServiceTLSTest {
private Vertx vertx;
private WebSocketConfiguration config;
private WebSocketMessageHandler webSocketMessageHandlerSpy;
@BeforeEach
public void setUp() {
vertx = Vertx.vertx();
config = WebSocketConfiguration.createDefault();
Map<String, JsonRpcMethod> websocketMethods;
config.setPort(0); // Use ephemeral port
config.setHost("localhost");
websocketMethods =
new WebSocketMethodsFactory(
new SubscriptionManager(new NoOpMetricsSystem()), new HashMap<>())
.methods();
webSocketMessageHandlerSpy =
spy(
new WebSocketMessageHandler(
vertx,
new JsonRpcExecutor(new BaseJsonRpcProcessor(), websocketMethods),
mock(EthScheduler.class),
TimeoutOptions.defaultOptions().getTimeoutSeconds()));
}
@Test
public void shouldAcceptSecureWebSocketConnection(final VertxTestContext testContext)
throws Throwable {
// Generate a self-signed certificate
SelfSignedCertificate ssc = new SelfSignedCertificate();
// Create a temporary keystore file
File keystoreFile = File.createTempFile("keystore", ".jks");
keystoreFile.deleteOnExit();
// Create a PKCS12 keystore and load the self-signed certificate
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);
keyStore.setKeyEntry(
"alias",
ssc.key(),
"password".toCharArray(),
new java.security.cert.Certificate[] {ssc.cert()});
// Save the keystore to the temporary file
try (FileOutputStream fos = new FileOutputStream(keystoreFile)) {
keyStore.store(fos, "password".toCharArray());
}
// Configure WebSocket with SSL enabled
config.setSslEnabled(true);
config.setKeyStorePath(keystoreFile.getAbsolutePath());
config.setKeyStorePassword("password");
config.setKeyStoreType("JKS");
// Create and start WebSocketService
WebSocketService webSocketService =
new WebSocketService(vertx, config, webSocketMessageHandlerSpy, new NoOpMetricsSystem());
webSocketService.start().join();
// Get the actual port
int port = webSocketService.socketAddress().getPort();
// Create a temporary truststore file
File truststoreFile = File.createTempFile("truststore", ".jks");
truststoreFile.deleteOnExit();
// Create a PKCS12 truststore and load the server's certificate
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(null, null);
trustStore.setCertificateEntry("alias", ssc.cert());
// Save the truststore to the temporary file
try (FileOutputStream fos = new FileOutputStream(truststoreFile)) {
trustStore.store(fos, "password".toCharArray());
}
// Configure the HTTP client with the truststore
WebSocketClientOptions clientOptions =
new WebSocketClientOptions()
.setSsl(true)
.setTrustOptions(
new JksOptions().setPath(truststoreFile.getAbsolutePath()).setPassword("password"))
.setVerifyHost(true);
WebSocketClient webSocketClient = vertx.createWebSocketClient(clientOptions);
webSocketClient
.connect(port, "localhost", "/")
.onSuccess(
ws -> {
assertThat(ws.isSsl()).isTrue();
ws.close();
testContext.completeNow();
})
.onFailure(testContext::failNow);
assertThat(testContext.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
if (testContext.failed()) {
throw testContext.causeOfFailure();
}
// Stop the WebSocketService after the test
webSocketService.stop().join();
}
@Test
public void shouldAcceptSecureWebSocketConnectionPEM(final VertxTestContext testContext)
throws Throwable {
// Generate a self-signed certificate
SelfSignedCertificate ssc = new SelfSignedCertificate();
// Create temporary PEM files for the certificate and key
File certFile = File.createTempFile("cert", ".pem");
certFile.deleteOnExit();
File keyFile = File.createTempFile("key", ".pem");
keyFile.deleteOnExit();
// Write the certificate and key to the PEM files
try (FileOutputStream certOut = new FileOutputStream(certFile);
FileOutputStream keyOut = new FileOutputStream(keyFile)) {
certOut.write("-----BEGIN CERTIFICATE-----\n".getBytes(UTF_8));
certOut.write(
Base64.getMimeEncoder(64, "\n".getBytes(UTF_8)).encode(ssc.cert().getEncoded()));
certOut.write("\n-----END CERTIFICATE-----\n".getBytes(UTF_8));
keyOut.write("-----BEGIN PRIVATE KEY-----\n".getBytes(UTF_8));
keyOut.write(Base64.getMimeEncoder(64, "\n".getBytes(UTF_8)).encode(ssc.key().getEncoded()));
keyOut.write("\n-----END PRIVATE KEY-----\n".getBytes(UTF_8));
}
// Configure WebSocket with SSL enabled using PEM files
config.setSslEnabled(true);
config.setKeyPath(keyFile.getAbsolutePath());
config.setCertPath(certFile.getAbsolutePath());
config.setKeyStoreType("PEM");
// Create and start WebSocketService
WebSocketService webSocketService =
new WebSocketService(vertx, config, webSocketMessageHandlerSpy, new NoOpMetricsSystem());
webSocketService.start().join();
// Get the actual port
int port = webSocketService.socketAddress().getPort();
// Create a temporary PEM file for the trust store
File trustCertFile = File.createTempFile("trust-cert", ".pem");
trustCertFile.deleteOnExit();
// Write the server's certificate to the PEM file
try (FileOutputStream trustCertOut = new FileOutputStream(trustCertFile)) {
trustCertOut.write("-----BEGIN CERTIFICATE-----\n".getBytes(UTF_8));
trustCertOut.write(
Base64.getMimeEncoder(64, "\n".getBytes(UTF_8)).encode(ssc.cert().getEncoded()));
trustCertOut.write("\n-----END CERTIFICATE-----\n".getBytes(UTF_8));
}
// Configure the HTTP client with the trust store using PEM files
WebSocketClientOptions clientOptions =
new WebSocketClientOptions()
.setSsl(true)
.setTrustOptions(new PemTrustOptions().addCertPath(trustCertFile.getAbsolutePath()))
.setVerifyHost(true);
WebSocketClient webSocketClient = vertx.createWebSocketClient(clientOptions);
webSocketClient
.connect(port, "localhost", "/")
.onSuccess(
ws -> {
assertThat(ws.isSsl()).isTrue();
ws.close();
testContext.completeNow();
})
.onFailure(testContext::failNow);
assertThat(testContext.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
if (testContext.failed()) {
throw testContext.causeOfFailure();
}
// Stop the WebSocketService after the test
webSocketService.stop().join();
}
@Test
public void shouldFailConnectionWithWrongCertificateInTrustStore(
final VertxTestContext testContext) throws Throwable {
// Generate a self-signed certificate for the server
SelfSignedCertificate serverCert = new SelfSignedCertificate();
// Create a temporary keystore file for the server
File keystoreFile = File.createTempFile("keystore", ".p12");
keystoreFile.deleteOnExit();
// Create a PKCS12 keystore and load the server's self-signed certificate
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null, null);
keyStore.setKeyEntry(
"alias",
serverCert.key(),
"password".toCharArray(),
new java.security.cert.Certificate[] {serverCert.cert()});
// Save the keystore to the temporary file
try (FileOutputStream fos = new FileOutputStream(keystoreFile)) {
keyStore.store(fos, "password".toCharArray());
}
// Configure WebSocket with SSL enabled
config.setSslEnabled(true);
config.setKeyStorePath(keystoreFile.getAbsolutePath());
config.setKeyStorePassword("password");
config.setKeyStoreType("PKCS12");
// Create and start WebSocketService
WebSocketService webSocketService =
new WebSocketService(vertx, config, webSocketMessageHandlerSpy, new NoOpMetricsSystem());
webSocketService.start().join();
// Get the actual port
int port = webSocketService.socketAddress().getPort();
// Generate a different self-signed certificate for the trust store
SelfSignedCertificate wrongCert = new SelfSignedCertificate();
// Create a temporary truststore file
File truststoreFile = File.createTempFile("truststore", ".p12");
truststoreFile.deleteOnExit();
// Create a PKCS12 truststore and load the wrong certificate
KeyStore trustStore = KeyStore.getInstance("PKCS12");
trustStore.load(null, null);
trustStore.setCertificateEntry("alias", wrongCert.cert());
// Save the truststore to the temporary file
try (FileOutputStream fos = new FileOutputStream(truststoreFile)) {
trustStore.store(fos, "password".toCharArray());
}
// Configure the HTTP client with the truststore containing the wrong certificate
WebSocketClientOptions clientOptions =
new WebSocketClientOptions()
.setSsl(true)
.setTrustOptions(
new JksOptions().setPath(truststoreFile.getAbsolutePath()).setPassword("password"))
.setVerifyHost(true);
WebSocketClient webSocketClient = vertx.createWebSocketClient(clientOptions);
webSocketClient
.connect(port, "localhost", "/")
.onSuccess(
ws -> {
testContext.failNow(new AssertionError("Connection should have been rejected"));
})
.onFailure(
throwable -> {
assertThat(throwable).isInstanceOf(Exception.class);
testContext.completeNow();
});
assertThat(testContext.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
if (testContext.failed()) {
throw testContext.causeOfFailure();
}
// Stop the WebSocketService after the test
webSocketService.stop().join();
}
@Test
public void shouldAuthenticateClient(final VertxTestContext testContext) throws Throwable {
// Generate a self-signed certificate for the server
SelfSignedCertificate serverCert = new SelfSignedCertificate();
// Generate a self-signed certificate for the client
SelfSignedCertificate clientCert = new SelfSignedCertificate();
// Create a temporary keystore file for the server
File serverKeystoreFile = File.createTempFile("keystore", ".p12");
serverKeystoreFile.deleteOnExit();
// Create a temporary truststore file for the server
File serverTruststoreFile = File.createTempFile("truststore", ".p12");
serverTruststoreFile.deleteOnExit();
// Create a temporary keystore file for the client
File clientKeystoreFile = File.createTempFile("client-keystore", ".p12");
clientKeystoreFile.deleteOnExit();
// Create a temporary truststore file for the client
File clientTruststoreFile = File.createTempFile("truststore", ".p12");
clientTruststoreFile.deleteOnExit();
// Create a PKCS12 keystore and load the server's self-signed certificate
KeyStore serverKeyStore = KeyStore.getInstance("PKCS12");
serverKeyStore.load(null, null);
serverKeyStore.setKeyEntry(
"alias",
serverCert.key(),
"password".toCharArray(),
new java.security.cert.Certificate[] {serverCert.cert()});
// Save the keystore to the temporary file
try (FileOutputStream fos = new FileOutputStream(serverKeystoreFile)) {
serverKeyStore.store(fos, "password".toCharArray());
}
// Create a PKCS12 truststore and load the client's self-signed certificate
KeyStore serverTrustStore = KeyStore.getInstance("PKCS12");
serverTrustStore.load(null, null);
serverTrustStore.setCertificateEntry("alias", clientCert.cert());
// Save the truststore to the temporary file
try (FileOutputStream fos = new FileOutputStream(serverTruststoreFile)) {
serverTrustStore.store(fos, "password".toCharArray());
}
// Create a PKCS12 keystore and load the client's self-signed certificate
KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");
clientKeyStore.load(null, null);
clientKeyStore.setKeyEntry(
"alias",
clientCert.key(),
"password".toCharArray(),
new java.security.cert.Certificate[] {clientCert.cert()});
// Save the client keystore to the temporary file
try (FileOutputStream fos = new FileOutputStream(clientKeystoreFile)) {
clientKeyStore.store(fos, "password".toCharArray());
}
// Create a PKCS12 truststore and load the server's self-signed certificate
KeyStore clientTrustStore = KeyStore.getInstance("PKCS12");
clientTrustStore.load(null, null);
clientTrustStore.setCertificateEntry("alias", serverCert.cert());
// Save the truststore to the temporary file
try (FileOutputStream fos = new FileOutputStream(clientTruststoreFile)) {
clientTrustStore.store(fos, "password".toCharArray());
}
// Configure WebSocket with SSL and client authentication enabled
config.setSslEnabled(true);
config.setKeyStorePath(serverKeystoreFile.getAbsolutePath());
config.setKeyStorePassword("password");
config.setKeyStoreType("PKCS12");
config.setClientAuthEnabled(true);
config.setTrustStorePath(serverTruststoreFile.getAbsolutePath());
config.setTrustStorePassword("password");
config.setTrustStoreType("PKCS12");
// Create and start WebSocketService
WebSocketService webSocketService =
new WebSocketService(vertx, config, webSocketMessageHandlerSpy, new NoOpMetricsSystem());
webSocketService.start().join();
// Get the actual port
int port = webSocketService.socketAddress().getPort();
// Configure the HTTP client with the client certificate
WebSocketClientOptions clientOptions =
new WebSocketClientOptions()
.setSsl(true)
.setKeyStoreOptions(
new JksOptions()
.setPath(clientKeystoreFile.getAbsolutePath())
.setPassword("password"))
.setTrustOptions(
new JksOptions()
.setPath(clientTruststoreFile.getAbsolutePath())
.setPassword("password"))
.setVerifyHost(true);
WebSocketClient webSocketClient = vertx.createWebSocketClient(clientOptions);
webSocketClient
.connect(port, "localhost", "/")
.onSuccess(
ws -> {
assertThat(ws.isSsl()).isTrue();
ws.close();
testContext.completeNow();
})
.onFailure(testContext::failNow);
assertThat(testContext.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
if (testContext.failed()) {
throw testContext.causeOfFailure();
}
// Stop the WebSocketService after the test
webSocketService.stop().join();
}
}

@ -181,7 +181,7 @@ public class MainnetBlockValidator implements BlockValidator {
Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests)));
}
} catch (MerkleTrieException ex) {
context.getSynchronizer().healWorldState(ex.getMaybeAddress(), ex.getLocation());
context.getWorldStateArchive().heal(ex.getMaybeAddress(), ex.getLocation());
return new BlockProcessingResult(Optional.empty(), ex);
} catch (StorageException ex) {
var retval = new BlockProcessingResult(Optional.empty(), ex);

@ -16,7 +16,6 @@ package org.hyperledger.besu.ethereum;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
@ -32,7 +31,6 @@ public class ProtocolContext {
private final WorldStateArchive worldStateArchive;
private final BadBlockManager badBlockManager;
private final ConsensusContext consensusContext;
private Synchronizer synchronizer;
/**
* Constructs a new ProtocolContext with the given blockchain, world state archive, consensus
@ -78,24 +76,6 @@ public class ProtocolContext {
badBlockManager);
}
/**
* Gets the synchronizer of the protocol context.
*
* @return the synchronizer of the protocol context
*/
public Synchronizer getSynchronizer() {
return synchronizer;
}
/**
* Sets the synchronizer of the protocol context.
*
* @param synchronizer the synchronizer to set
*/
public void setSynchronizer(final Synchronizer synchronizer) {
this.synchronizer = synchronizer;
}
/**
* Gets the blockchain of the protocol context.
*

@ -34,6 +34,7 @@ import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import com.google.common.annotations.VisibleForTesting;
import org.apache.tuweni.bytes.Bytes;
@ -44,6 +45,7 @@ public class BonsaiWorldStateProvider extends DiffBasedWorldStateProvider {
private static final Logger LOG = LoggerFactory.getLogger(BonsaiWorldStateProvider.class);
private final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader;
private final Supplier<WorldStateHealer> worldStateHealerSupplier;
public BonsaiWorldStateProvider(
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage,
@ -51,9 +53,11 @@ public class BonsaiWorldStateProvider extends DiffBasedWorldStateProvider {
final Optional<Long> maxLayersToLoad,
final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader,
final BesuContext pluginContext,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final Supplier<WorldStateHealer> worldStateHealerSupplier) {
super(worldStateKeyValueStorage, blockchain, maxLayersToLoad, pluginContext);
this.bonsaiCachedMerkleTrieLoader = bonsaiCachedMerkleTrieLoader;
this.worldStateHealerSupplier = worldStateHealerSupplier;
provideCachedWorldStorageManager(
new BonsaiCachedWorldStorageManager(
this, worldStateKeyValueStorage, this::cloneBonsaiWorldStateConfig));
@ -69,9 +73,11 @@ public class BonsaiWorldStateProvider extends DiffBasedWorldStateProvider {
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage,
final Blockchain blockchain,
final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader,
final EvmConfiguration evmConfiguration) {
final EvmConfiguration evmConfiguration,
final Supplier<WorldStateHealer> worldStateHealerSupplier) {
super(worldStateKeyValueStorage, blockchain, trieLogManager);
this.bonsaiCachedMerkleTrieLoader = bonsaiCachedMerkleTrieLoader;
this.worldStateHealerSupplier = worldStateHealerSupplier;
provideCachedWorldStorageManager(bonsaiCachedWorldStorageManager);
loadPersistedState(
new BonsaiWorldState(
@ -151,4 +157,9 @@ public class BonsaiWorldStateProvider extends DiffBasedWorldStateProvider {
private DiffBasedWorldStateConfig cloneBonsaiWorldStateConfig() {
return new DiffBasedWorldStateConfig(defaultWorldStateConfig);
}
@Override
public void heal(final Optional<Address> maybeAccountToRepair, final Bytes location) {
worldStateHealerSupplier.get().heal(maybeAccountToRepair, location);
}
}

@ -112,6 +112,11 @@ public class ForestWorldStateArchive implements WorldStateArchive {
blockHeader.getStateRoot(), accountAddress, accountStorageKeys));
}
@Override
public void heal(final Optional<Address> maybeAccountToRepair, final Bytes location) {
// no heal needed for Forest
}
@Override
public void close() {
// no op

@ -64,4 +64,24 @@ public interface WorldStateArchive extends Closeable {
final Address accountAddress,
final List<UInt256> accountStorageKeys,
final Function<Optional<WorldStateProof>, ? extends Optional<U>> mapper);
/**
* Heal the world state to fix inconsistency
*
* @param maybeAccountToRepair the optional account to repair
* @param location the location of the inconsistency
*/
void heal(Optional<Address> maybeAccountToRepair, Bytes location);
/** A world state healer */
@FunctionalInterface
interface WorldStateHealer {
/**
* Heal the world state to fix inconsistency
*
* @param maybeAccountToRepair the optional account to repair
* @param location the location of the inconsistency
*/
void heal(Optional<Address> maybeAccountToRepair, Bytes location);
}
}

@ -194,7 +194,6 @@ public class BlockchainSetupUtil {
genesisState.writeStateTo(worldArchive.getMutable());
final ProtocolContext protocolContext = protocolContextProvider.get(blockchain, worldArchive);
protocolContext.setSynchronizer(new DummySynchronizer());
final Path blocksPath = Path.of(chainResources.getBlocksURL().toURI());
final List<Block> blocks = new ArrayList<>();

@ -14,6 +14,8 @@
*/
package org.hyperledger.besu.ethereum.core;
import static org.hyperledger.besu.ethereum.core.WorldStateHealerHelper.throwingWorldStateHealerSupplier;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
@ -105,7 +107,8 @@ public class InMemoryKeyValueStorageProvider extends KeyValueStorageProvider {
Optional.empty(),
bonsaiCachedMerkleTrieLoader,
null,
evmConfiguration);
evmConfiguration,
throwingWorldStateHealerSupplier());
}
public static MutableWorldState createInMemoryWorldState() {

@ -0,0 +1,39 @@
/*
* Copyright contributors to Besu.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.core;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive.WorldStateHealer;
import java.util.Optional;
import java.util.function.Supplier;
import org.apache.tuweni.bytes.Bytes;
public class WorldStateHealerHelper {
public static WorldStateHealer throwingHealer(
final Optional<Address> maybeAccountToRepair, final Bytes location) {
throw new RuntimeException(
"World state needs to be healed: "
+ maybeAccountToRepair.map(address -> "account to repair: " + address).orElse("")
+ " location: "
+ location.toHexString());
}
public static Supplier<WorldStateHealer> throwingWorldStateHealerSupplier() {
return () -> WorldStateHealerHelper::throwingHealer;
}
}

@ -31,7 +31,6 @@ import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.mainnet.BlockBodyValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockProcessor;
@ -91,7 +90,6 @@ public class MainnetBlockValidatorTest {
when(protocolContext.getBlockchain()).thenReturn(blockchain);
when(protocolContext.getWorldStateArchive()).thenReturn(worldStateArchive);
when(protocolContext.getSynchronizer()).thenReturn(mock(Synchronizer.class));
when(worldStateArchive.getMutable(any(BlockHeader.class), anyBoolean()))
.thenReturn(Optional.of(worldState));
when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class)))

@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.trie.diffbased.bonsai;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
import static org.hyperledger.besu.ethereum.core.WorldStateHealerHelper.throwingWorldStateHealerSupplier;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
@ -167,7 +168,8 @@ public abstract class AbstractIsolationTests {
Optional.of(16L),
new BonsaiCachedMerkleTrieLoader(new NoOpMetricsSystem()),
null,
EvmConfiguration.DEFAULT);
EvmConfiguration.DEFAULT,
throwingWorldStateHealerSupplier());
var ws = archive.getMutable();
genesisState.writeStateTo(ws);
protocolContext = new ProtocolContext(blockchain, archive, null, new BadBlockManager());

@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.trie.diffbased.bonsai;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.core.WorldStateHealerHelper.throwingWorldStateHealerSupplier;
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.BLOCKCHAIN;
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE;
import static org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage.WORLD_BLOCK_HASH_KEY;
@ -111,7 +112,8 @@ class BonsaiWorldStateProviderTest {
DataStorageConfiguration.DEFAULT_BONSAI_CONFIG),
blockchain,
new BonsaiCachedMerkleTrieLoader(new NoOpMetricsSystem()),
EvmConfiguration.DEFAULT);
EvmConfiguration.DEFAULT,
throwingWorldStateHealerSupplier());
assertThat(bonsaiWorldStateArchive.getMutable(chainHead, true))
.containsInstanceOf(BonsaiWorldState.class);
@ -129,7 +131,8 @@ class BonsaiWorldStateProviderTest {
Optional.of(512L),
new BonsaiCachedMerkleTrieLoader(new NoOpMetricsSystem()),
null,
EvmConfiguration.DEFAULT);
EvmConfiguration.DEFAULT,
throwingWorldStateHealerSupplier());
final BlockHeader blockHeader = blockBuilder.number(0).buildHeader();
final BlockHeader chainHead = blockBuilder.number(512).buildHeader();
when(blockchain.getChainHeadHeader()).thenReturn(chainHead);
@ -150,7 +153,8 @@ class BonsaiWorldStateProviderTest {
DataStorageConfiguration.DEFAULT_BONSAI_CONFIG),
blockchain,
new BonsaiCachedMerkleTrieLoader(new NoOpMetricsSystem()),
EvmConfiguration.DEFAULT);
EvmConfiguration.DEFAULT,
throwingWorldStateHealerSupplier());
final BlockHeader blockHeader = blockBuilder.number(0).buildHeader();
final BlockHeader chainHead = blockBuilder.number(511).buildHeader();
final BonsaiWorldState mockWorldState = mock(BonsaiWorldState.class);
@ -185,7 +189,8 @@ class BonsaiWorldStateProviderTest {
worldStateKeyValueStorage,
blockchain,
new BonsaiCachedMerkleTrieLoader(new NoOpMetricsSystem()),
EvmConfiguration.DEFAULT));
EvmConfiguration.DEFAULT,
throwingWorldStateHealerSupplier()));
final BlockHeader blockHeader = blockBuilder.number(0).buildHeader();
when(blockchain.getBlockHeader(blockHeader.getHash())).thenReturn(Optional.of(blockHeader));
@ -214,7 +219,8 @@ class BonsaiWorldStateProviderTest {
worldStateKeyValueStorage,
blockchain,
new BonsaiCachedMerkleTrieLoader(new NoOpMetricsSystem()),
EvmConfiguration.DEFAULT));
EvmConfiguration.DEFAULT,
throwingWorldStateHealerSupplier()));
final BlockHeader blockHeader = blockBuilder.number(0).buildHeader();
@ -254,7 +260,8 @@ class BonsaiWorldStateProviderTest {
worldStateKeyValueStorage,
blockchain,
new BonsaiCachedMerkleTrieLoader(new NoOpMetricsSystem()),
EvmConfiguration.DEFAULT));
EvmConfiguration.DEFAULT,
throwingWorldStateHealerSupplier()));
// initial persisted state hash key
when(blockchain.getBlockHeader(Hash.ZERO)).thenReturn(Optional.of(blockHeaderChainA));
@ -297,7 +304,8 @@ class BonsaiWorldStateProviderTest {
DataStorageConfiguration.DEFAULT_BONSAI_CONFIG),
blockchain,
new BonsaiCachedMerkleTrieLoader(new NoOpMetricsSystem()),
EvmConfiguration.DEFAULT));
EvmConfiguration.DEFAULT,
throwingWorldStateHealerSupplier()));
// initial persisted state hash key
when(blockchain.getBlockHeader(Hash.ZERO)).thenReturn(Optional.of(blockHeaderChainA));

@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.eth.manager.snap;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.eth.SnapProtocol;
import org.hyperledger.besu.ethereum.eth.manager.EthMessage;
import org.hyperledger.besu.ethereum.eth.manager.EthMessages;
@ -53,11 +54,13 @@ public class SnapProtocolManager implements ProtocolManager {
final SnapSyncConfiguration snapConfig,
final EthPeers ethPeers,
final EthMessages snapMessages,
final ProtocolContext protocolContext) {
final ProtocolContext protocolContext,
final Synchronizer synchronizer) {
this.ethPeers = ethPeers;
this.snapMessages = snapMessages;
this.supportedCapabilities = calculateCapabilities();
new SnapServer(snapConfig, snapMessages, worldStateStorageCoordinator, protocolContext);
new SnapServer(
snapConfig, snapMessages, worldStateStorageCoordinator, protocolContext, synchronizer);
}
private List<Capability> calculateCapabilities() {

@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.eth.manager.snap;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.eth.manager.EthMessages;
import org.hyperledger.besu.ethereum.eth.messages.snap.AccountRangeMessage;
import org.hyperledger.besu.ethereum.eth.messages.snap.ByteCodesMessage;
@ -98,7 +99,8 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener {
final SnapSyncConfiguration snapConfig,
final EthMessages snapMessages,
final WorldStateStorageCoordinator worldStateStorageCoordinator,
final ProtocolContext protocolContext) {
final ProtocolContext protocolContext,
final Synchronizer synchronizer) {
this.snapServerEnabled =
Optional.ofNullable(snapConfig)
.map(SnapSyncConfiguration::isSnapServerEnabled)
@ -110,7 +112,7 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener {
// subscribe to initial sync completed events to start/stop snap server,
// not saving the listenerId since we never need to unsubscribe.
protocolContext.getSynchronizer().subscribeInitialSync(this);
synchronizer.subscribeInitialSync(this);
}
/**

@ -37,7 +37,8 @@ import com.google.common.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TransactionBroadcaster implements TransactionBatchAddedListener {
public class TransactionBroadcaster
implements TransactionBatchAddedListener, PendingTransactionDroppedListener {
private static final Logger LOG = LoggerFactory.getLogger(TransactionBroadcaster.class);
private static final EnumSet<TransactionType> ANNOUNCE_HASH_ONLY_TX_TYPES = EnumSet.of(BLOB);
@ -219,4 +220,9 @@ public class TransactionBroadcaster implements TransactionBatchAddedListener {
destinationList.add(sourceList.remove(i));
}
}
@Override
public void onTransactionDropped(final Transaction transaction, final RemovalReason reason) {
transactionTracker.onTransactionDropped(transaction, reason);
}
}

@ -139,6 +139,7 @@ public class TransactionPool implements BlockAddedObserver {
subscribePendingTransactions(this::mapBlobsOnTransactionAdded);
subscribeDroppedTransactions(
(transaction, reason) -> unmapBlobsOnTransactionDropped(transaction));
subscribeDroppedTransactions(transactionBroadcaster);
}
private void initLogForReplay() {

@ -15,10 +15,12 @@
package org.hyperledger.besu.ethereum.eth.manager.snap;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.eth.manager.EthMessages;
import org.hyperledger.besu.ethereum.eth.messages.snap.AccountRangeMessage;
import org.hyperledger.besu.ethereum.eth.messages.snap.GetAccountRangeMessage;
@ -70,7 +72,8 @@ public class SnapServerGetAccountRangeTest {
snapSyncConfiguration,
new EthMessages(),
worldStateStorageCoordinator,
protocolContext)
protocolContext,
mock(Synchronizer.class))
.start();
initAccounts();
}

@ -1932,6 +1932,14 @@
<sha256 value="cf743ff8a0143fe3fc6a803f0b225014c23b5a2ea25632bf704c07845386d3af" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-all" version="4.1.115.Final">
<artifact name="netty-all-4.1.115.Final.jar">
<sha256 value="c1c3092e02e8037c18d14034919af68d573a71e7118db48129e6f299b9a71adc" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-all-4.1.115.Final.pom">
<sha256 value="63bc9f25de4e53d6b7fee665fa5e4c73236a4015af3d388db99038b84f79fef5" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-bom" version="4.1.111.Final">
<artifact name="netty-bom-4.1.111.Final.pom">
<sha256 value="2f113902364208bbb32d551e062b05ab219692fbc12bd48de1d83c7576e5b470" origin="Generated by Gradle"/>
@ -1942,6 +1950,11 @@
<sha256 value="0dfd08abc106f625be1d6eb498fa993de65c8b558070dfb11afa9a3394bb6612" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-bom" version="4.1.115.Final">
<artifact name="netty-bom-4.1.115.Final.pom">
<sha256 value="25dc8bb8337dfc186c49fc8cf4f6a5b6c7cf4146362f5f440dacadcd0df9761b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-buffer" version="4.1.111.Final">
<artifact name="netty-buffer-4.1.111.Final.pom">
<sha256 value="6afc7e751e0a90d2cb1168f6a4854d80bf3ba888104afab303233cd31684f4b4" origin="Generated by Gradle"/>
@ -1955,6 +1968,14 @@
<sha256 value="b3f07cf4271ee5a4a459ea8a0d9f4f16911a9355357831d05710ef64f8b8c5ce" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-buffer" version="4.1.115.Final">
<artifact name="netty-buffer-4.1.115.Final.jar">
<sha256 value="4a7b331d3770c566ab70eb02a0d1feed63b95cf6e4d68c8fe778c4c9de2d116d" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-buffer-4.1.115.Final.pom">
<sha256 value="94a3581ea9e4ffc385bb237960f68ef1e84089f164eae8629e8fd66d8aaf0139" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec" version="4.1.114.Final">
<artifact name="netty-codec-4.1.114.Final.jar">
<sha256 value="71d145491456b53212e38e24787bbbed0c77d850f7352e24e535d26a6eea913b" origin="Generated by Gradle"/>
@ -1963,6 +1984,14 @@
<sha256 value="f55160abec463634c36459914cc60cb59489dcb723e87e9a71ac37bdf3706b84" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec" version="4.1.115.Final">
<artifact name="netty-codec-4.1.115.Final.jar">
<sha256 value="cd189afb70ec6eacfcdfdd3a5f472b4e705a5c91d5bd3ef0386421f2ae15ec77" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-4.1.115.Final.pom">
<sha256 value="ac166597e81179ca8300276605408910cc030efec12236ce9c38fefc16801aa0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-dns" version="4.1.114.Final">
<artifact name="netty-codec-dns-4.1.114.Final.jar">
<sha256 value="7b97b856d062e7b2483384223dcee002ad23d526f827991f1140af6302ca120d" origin="Generated by Gradle"/>
@ -1971,6 +2000,14 @@
<sha256 value="24577daa4d8ab270fd6dc51d1ecca5be383e3df14450d35ae83e048d9981aa32" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-dns" version="4.1.115.Final">
<artifact name="netty-codec-dns-4.1.115.Final.jar">
<sha256 value="23dd6806bcc326855f13e69838c6411d0490e6b1aeb12e217a19a3dd6ad3f10d" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-dns-4.1.115.Final.pom">
<sha256 value="73976d702597a4d7597f82634fd17d1161a486972c7306b7e7cccb582533ea4e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-haproxy" version="4.1.114.Final">
<artifact name="netty-codec-haproxy-4.1.114.Final.jar">
<sha256 value="a96216d347c7219f69b2f4f8743ce0aee6ac750b3691739745ebbcc10eb49528" origin="Generated by Gradle"/>
@ -1979,6 +2016,14 @@
<sha256 value="a399be4607a97549d249ad76f2fcf6e092af63d344e3272efd44df21757ccfe0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-haproxy" version="4.1.115.Final">
<artifact name="netty-codec-haproxy-4.1.115.Final.jar">
<sha256 value="7514f1d10dda3af9468b57bbb0f63fe0b8abb55dbb8190bede95319f37228322" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-haproxy-4.1.115.Final.pom">
<sha256 value="83e802589a080559e692e554a382119d9f88e5145b09fa4cc130a2655c44f8b4" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-http" version="4.1.111.Final">
<artifact name="netty-codec-http-4.1.111.Final.pom">
<sha256 value="80372e3e6e61ba8b3abe623964c986376568b6bbec705adb29d2a959cd7b9f8c" origin="Generated by Gradle"/>
@ -1992,6 +2037,14 @@
<sha256 value="e8fe9ebb862f1dd5c3a6be87e851a3b3b28a7eec4af8d70acbecb0c1e816f3ae" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-http" version="4.1.115.Final">
<artifact name="netty-codec-http-4.1.115.Final.jar">
<sha256 value="e6dbe971c59373bbae9802021c63b9bc1d8800fead382863d67e79e79b023166" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-http-4.1.115.Final.pom">
<sha256 value="fa7064f72ee52e136c9b6bfb5a1a0d510dcb73092d71941a39514c322a59de40" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-http2" version="4.1.111.Final">
<artifact name="netty-codec-http2-4.1.111.Final.pom">
<sha256 value="c7f0325aa4c75c9eae1e388306dc7d10426c6a2a6c8f712f876f58a4bc157ede" origin="Generated by Gradle"/>
@ -2005,6 +2058,14 @@
<sha256 value="a856ee4a1cc7d497b664b9125b3c90a690091ff771beca2a9858d51858a75850" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-http2" version="4.1.115.Final">
<artifact name="netty-codec-http2-4.1.115.Final.jar">
<sha256 value="cbed9829a5d582e91e314e209edce9a0c2eb369f23bb4fb74a5bc8b7990222c2" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-http2-4.1.115.Final.pom">
<sha256 value="88747b3e38e21cc1f42eaa44d301423482c0fc26c467b3f78fb9edfbde93a3e1" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-memcache" version="4.1.114.Final">
<artifact name="netty-codec-memcache-4.1.114.Final.jar">
<sha256 value="7ef9cfa35408cf43196ad41b7d31517d4a29fbc3c52f387f7c1930ebc02e3c3b" origin="Generated by Gradle"/>
@ -2013,6 +2074,14 @@
<sha256 value="9748096cc41e8de6c78d4cea259ea222a7af70756f783b612b83c9f36e62e848" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-memcache" version="4.1.115.Final">
<artifact name="netty-codec-memcache-4.1.115.Final.jar">
<sha256 value="c44561d5cdb0e28e63b00dccb51c8f293c8b23012e0299042804e054e2b05fab" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-memcache-4.1.115.Final.pom">
<sha256 value="cfcc9845b932975dfc13be8c19260fda48d0646003de0e017964bdcde24d37c6" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-mqtt" version="4.1.114.Final">
<artifact name="netty-codec-mqtt-4.1.114.Final.jar">
<sha256 value="4e5d5e05a26399f8431beb61fb4860b554938bbfba9d633cfb8c69444a089cc8" origin="Generated by Gradle"/>
@ -2021,6 +2090,14 @@
<sha256 value="e31ab2e3030a3a3b10ab85abe6547f9c214de55d5b69251dee76367c6bf6ab98" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-mqtt" version="4.1.115.Final">
<artifact name="netty-codec-mqtt-4.1.115.Final.jar">
<sha256 value="54202f894eea7f235b8f9032b32a09396bbf92a68cb32a486981ced96eb85222" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-mqtt-4.1.115.Final.pom">
<sha256 value="dc966366eac6d123a56357a34495400435ed2c48f9bab5b363d648ddb525abba" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-redis" version="4.1.114.Final">
<artifact name="netty-codec-redis-4.1.114.Final.jar">
<sha256 value="8b31e03a59c4d460f9f6306a6b8ef1ee856f93a24ed94f8e47fc2cd0d77ffd0d" origin="Generated by Gradle"/>
@ -2029,6 +2106,14 @@
<sha256 value="520a82274a95583df659bb7b2a70ad8864396f02e6fefcd989f688f18f5748c9" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-redis" version="4.1.115.Final">
<artifact name="netty-codec-redis-4.1.115.Final.jar">
<sha256 value="eddc930ecb65055a202b4d959f7b6636085a468d45daf283725037d466fa4de1" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-redis-4.1.115.Final.pom">
<sha256 value="3afc90b1246694810d9da24e60a057cc2db5e44f20d820dfee67357d621a2975" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-smtp" version="4.1.114.Final">
<artifact name="netty-codec-smtp-4.1.114.Final.jar">
<sha256 value="78285748b6e50b2275e32579353638424afdc117e3919c9a01fd8deb4974a6d8" origin="Generated by Gradle"/>
@ -2037,6 +2122,14 @@
<sha256 value="20219aaaaf7a534b5f0d142ca39f83234273069eb6f59779818e94f4c3630b1c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-smtp" version="4.1.115.Final">
<artifact name="netty-codec-smtp-4.1.115.Final.jar">
<sha256 value="caa622c91fae41a0396b576c3803955371ae9ccde3ba6bf46117f4b641d0f737" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-smtp-4.1.115.Final.pom">
<sha256 value="f249c4744b45bea1147755c57a98d093b65925d684a249e8ec06d7bb360f687d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-socks" version="4.1.114.Final">
<artifact name="netty-codec-socks-4.1.114.Final.jar">
<sha256 value="2e48cb5af7cae82acbb8dcb7b0c9d67b9dddff3d6dd262cb8911fd4b5fd62ee2" origin="Generated by Gradle"/>
@ -2045,6 +2138,14 @@
<sha256 value="374f2d39e95f0106a22d4e4c42c5ed6f377027a61c6e8f1bf72b0fb12823da06" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-socks" version="4.1.115.Final">
<artifact name="netty-codec-socks-4.1.115.Final.jar">
<sha256 value="e9b1cc744dc6195894450b1fd4d271a821ab167fe21ae3c459b27cdadc70e81f" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-socks-4.1.115.Final.pom">
<sha256 value="08b3c1acc77abdbadeef08c8cdf080e1bcceffe5f84751f60d89fc0bcbaaa2fc" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-stomp" version="4.1.114.Final">
<artifact name="netty-codec-stomp-4.1.114.Final.jar">
<sha256 value="9b63156b727843485b137c87e2c7e4c7db2690f5ca93443080711a1804d685cf" origin="Generated by Gradle"/>
@ -2053,6 +2154,14 @@
<sha256 value="d4e8f0900d3dd2e6d9f74bbae8b4b427c21c8b18f388a41b0205ae7f0335ac20" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-stomp" version="4.1.115.Final">
<artifact name="netty-codec-stomp-4.1.115.Final.jar">
<sha256 value="9470312b5e263595a4d0a6a3cb3e64e5d11e87285fbfc267b845118d1c26fc7a" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-stomp-4.1.115.Final.pom">
<sha256 value="394fd6bdf7145aa180548d46f3297ed6a9e6a4a073fe0f743ca4df8217b1990a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-xml" version="4.1.114.Final">
<artifact name="netty-codec-xml-4.1.114.Final.jar">
<sha256 value="3a2055a9b38b603ea9fcbfbe891172daad60df99aecd99161f1c8adbedc95522" origin="Generated by Gradle"/>
@ -2061,6 +2170,14 @@
<sha256 value="e5fcbcb730801bf08dc5b8575b2545766a61331e0e285d05fd805602564deb5f" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-codec-xml" version="4.1.115.Final">
<artifact name="netty-codec-xml-4.1.115.Final.jar">
<sha256 value="e1c5f043f027ca5f853076df16c233665011be60a81f5a6f7336093790a9dced" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-codec-xml-4.1.115.Final.pom">
<sha256 value="aa98be6f2de38ece5a34492c1ae1c22d6783aa88cf74f1b1eb3d46add5bf514b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-common" version="4.1.111.Final">
<artifact name="netty-common-4.1.111.Final.pom">
<sha256 value="b9c78337616bf8d54d5515bab6cba1df2db46fdb01b412434cc7fbafe78345c5" origin="Generated by Gradle"/>
@ -2074,6 +2191,14 @@
<sha256 value="3c2e7d18133ac6d8e4f442cc5fa5fe0492f5cbf878bf0f7157c6d410da719f5d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-common" version="4.1.115.Final">
<artifact name="netty-common-4.1.115.Final.jar">
<sha256 value="39f1b5a2aaa4eab5d036dfd0486e35a4276df412e092d36b2d88b494705a134d" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-common-4.1.115.Final.pom">
<sha256 value="6286361f5dd6a7b26c42909242bb8629e3aeec255ad0d3ff131bcb5152c31b21" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-handler" version="4.1.111.Final">
<artifact name="netty-handler-4.1.111.Final.pom">
<sha256 value="f575d446fa5cd546be4fce0bbf34c144041761b89da77971e30bf83d42905d1b" origin="Generated by Gradle"/>
@ -2087,6 +2212,14 @@
<sha256 value="694fe6fb8dfe9148a2326e77f56141fcebbccc2cb8b29f285776796164ec6a93" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-handler" version="4.1.115.Final">
<artifact name="netty-handler-4.1.115.Final.jar">
<sha256 value="5972028cc863b74927ce0d11fb8d58f65da2560bef5602fe8ce8903bd306ca07" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-handler-4.1.115.Final.pom">
<sha256 value="8c28025a352fc03846ce04960ab9843418bc6c82cbe5459e8060a4f3459efe90" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-handler-proxy" version="4.1.111.Final">
<artifact name="netty-handler-proxy-4.1.111.Final.pom">
<sha256 value="8577aa45f16f435b12420a37b8c8d731df11d4dcb7e132c00fc588946274ed89" origin="Generated by Gradle"/>
@ -2100,6 +2233,14 @@
<sha256 value="6cdaeb2a8f240fa1b72382476e2776969535678203d9902f3e63ef586ac0dbb7" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-handler-proxy" version="4.1.115.Final">
<artifact name="netty-handler-proxy-4.1.115.Final.jar">
<sha256 value="807e67cfb17136927d11db42df62031169d1fa0883e13f254906994c84ffbe87" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-handler-proxy-4.1.115.Final.pom">
<sha256 value="f9936b2da7adcecef5c4ffad772067b7de5d0e359b83e6fd39b4a49d11706a10" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-handler-ssl-ocsp" version="4.1.114.Final">
<artifact name="netty-handler-ssl-ocsp-4.1.114.Final.jar">
<sha256 value="c97e307e99bb9555adae0f01ddcd690965408aa1b653122fc7a02030dd73d8f7" origin="Generated by Gradle"/>
@ -2108,6 +2249,14 @@
<sha256 value="d217e882bd1fa6fbc6bfa3966b68fcade287ec6806c26ab9b0d80d4fc9daa694" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-handler-ssl-ocsp" version="4.1.115.Final">
<artifact name="netty-handler-ssl-ocsp-4.1.115.Final.jar">
<sha256 value="d958f728bffe9a2f23f32a70917a2842feb4fac59baec581f89411c734b59cfe" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-handler-ssl-ocsp-4.1.115.Final.pom">
<sha256 value="a4e8fdffeb1006d7ebb0c4b5cf70b4e7a81a533c783721b0d18d3c4403ffe883" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-parent" version="4.1.111.Final">
<artifact name="netty-parent-4.1.111.Final.pom">
<sha256 value="96b055ae7af7f1e32db3d7261918d900fba15e1e589ccd682f9cfd5744249a51" origin="Generated by Gradle"/>
@ -2118,6 +2267,11 @@
<sha256 value="a1c8a553ae7e43bf0ed986d22f0379dcf0c2fb7fc3971dc6057ed5c9d04c5a68" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-parent" version="4.1.115.Final">
<artifact name="netty-parent-4.1.115.Final.pom">
<sha256 value="d832942b8e2a71c2ccfdd0247a8b840105ce40aaeec4b8de36358f28d93941e3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-resolver" version="4.1.111.Final">
<artifact name="netty-resolver-4.1.111.Final.pom">
<sha256 value="d7524053459d425c9cbbbf93f0793504c4d0148c75fb49daab3e14d4e4d38ef0" origin="Generated by Gradle"/>
@ -2131,6 +2285,14 @@
<sha256 value="86843905401f6605d575f4858b58c1eadcf1e3c0bccd417787cb0ad0621cc120" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-resolver" version="4.1.115.Final">
<artifact name="netty-resolver-4.1.115.Final.jar">
<sha256 value="7b3455d14f59828765a00573bc3967dc59379e874bd62a67eb1926d6512109d1" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-resolver-4.1.115.Final.pom">
<sha256 value="53a491cfc876083ebd67e9c315c18c2348bb28f5366ca5d178bd8e8611f0ab4e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-resolver-dns" version="4.1.111.Final">
<artifact name="netty-resolver-dns-4.1.111.Final.pom">
<sha256 value="9d4607157d264015d8e8ae825d49fb8d8bf48fe227de99d82fb5570ac519c70a" origin="Generated by Gradle"/>
@ -2144,6 +2306,14 @@
<sha256 value="ed126dff491fe7175d0069141ca53ecb594c486c290c2ee13e99d25d72456fb4" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-resolver-dns" version="4.1.115.Final">
<artifact name="netty-resolver-dns-4.1.115.Final.jar">
<sha256 value="4aca31593e5896c64ab7e041bbc6c0d851bd9634ec3a4354208141a35576619f" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-resolver-dns-4.1.115.Final.pom">
<sha256 value="8d1e3143825e0244e1dd614b2340deb00f4ee07ef615faa855bd195100776789" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-resolver-dns-classes-macos" version="4.1.114.Final">
<artifact name="netty-resolver-dns-classes-macos-4.1.114.Final.jar">
<sha256 value="2bc4078cf269a99e09f28738d6022c385a31f4321e28115bae752ce16ce99618" origin="Generated by Gradle"/>
@ -2152,6 +2322,14 @@
<sha256 value="e530a68c73ea6f1c0a78c616ff29ce0a7a7a22f86ebcef27fa02965e6acbd660" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-resolver-dns-classes-macos" version="4.1.115.Final">
<artifact name="netty-resolver-dns-classes-macos-4.1.115.Final.jar">
<sha256 value="5fbac6346b3fc2fbdce7f7f24bb96a1b3190aa14d50021303a0a4437f3d373bc" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-resolver-dns-classes-macos-4.1.115.Final.pom">
<sha256 value="221aabb31073eea980d9de5a00a5b74ddaa99cccae638ad485dce8897d880c72" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-resolver-dns-native-macos" version="4.1.114.Final">
<artifact name="netty-resolver-dns-native-macos-4.1.114.Final-osx-aarch_64.jar">
<sha256 value="c63ffafc1becb7e1dca29c89b1c69ea74cc62abe3fcc3184ea7f089c76bac643" origin="Generated by Gradle"/>
@ -2163,6 +2341,17 @@
<sha256 value="710dbb92f3edbe204aea06dada1671f2382cd369f0ea47e6d5e03d0aa684929c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-resolver-dns-native-macos" version="4.1.115.Final">
<artifact name="netty-resolver-dns-native-macos-4.1.115.Final-osx-aarch_64.jar">
<sha256 value="a386a63e9c3d5a66130d1eebe9818820ca04d79769ab18b65d934e6e3a74e4e5" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-resolver-dns-native-macos-4.1.115.Final-osx-x86_64.jar">
<sha256 value="849d362370a74e14990a1a7cbcfd9fdbb2e1dbefc64a49d11fac34d8db36b859" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-resolver-dns-native-macos-4.1.115.Final.pom">
<sha256 value="f037922e4384b71959204e880e0564e448afd8d2066fc46f9caee528cda0ba44" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-tcnative-boringssl-static" version="2.0.65.Final">
<artifact name="netty-tcnative-boringssl-static-2.0.65.Final.pom">
<sha256 value="ba89f115a8c30bdbcb6dba36849a047da803b496f3e856e4365d53df1403932d" origin="Generated by Gradle"/>
@ -2176,6 +2365,14 @@
<sha256 value="7ea6c8ee65df3595dfc044ed2e95614acecab6da0b348b7a1e9361cba44fce2f" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-tcnative-boringssl-static" version="2.0.69.Final">
<artifact name="netty-tcnative-boringssl-static-2.0.69.Final.jar">
<sha256 value="79dbae7f0c2a1f73a6b4bb992edb0ab94ebd3196f5e83a94784039fb96d9a040" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-tcnative-boringssl-static-2.0.69.Final.pom">
<sha256 value="d55ff689622b75dfeca232da2a98cefa1773b7717a318be18113ebf718d232f8" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-tcnative-classes" version="2.0.66.Final">
<artifact name="netty-tcnative-classes-2.0.66.Final.jar">
<sha256 value="669a811a193dc1e7c9ef86cb547a4ab92f0f34cce8f9b842b9029bf5cfa07cc5" origin="Generated by Gradle"/>
@ -2184,11 +2381,24 @@
<sha256 value="4942cd02e2916c1fb4f78cca8841f0f7219bb90f828ab7489a89027c2efa91eb" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-tcnative-classes" version="2.0.69.Final">
<artifact name="netty-tcnative-classes-2.0.69.Final.jar">
<sha256 value="0bbc2848cb099eb3f6f4ec36501b3600e1828457cda41d5330687f601ee04bef" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-tcnative-classes-2.0.69.Final.pom">
<sha256 value="59da0f949e2bee89f5711eb3e0c6fd8cf7914e6b70c007f36b9eb0688243015c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-tcnative-parent" version="2.0.66.Final">
<artifact name="netty-tcnative-parent-2.0.66.Final.pom">
<sha256 value="2b017fb3c1deeab5d1eaebec134659b7deae78c14d5ebfc3d49c0b3084ea7365" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-tcnative-parent" version="2.0.69.Final">
<artifact name="netty-tcnative-parent-2.0.69.Final.pom">
<sha256 value="2953027196637610c894f32bda705093cd8768315c9f1a573951a75f17869afc" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport" version="4.1.111.Final">
<artifact name="netty-transport-4.1.111.Final.pom">
<sha256 value="8662bd5d7f62d372548f40ad896b87ea55c2b1d179029ef985837dce43a52269" origin="Generated by Gradle"/>
@ -2202,6 +2412,14 @@
<sha256 value="9451b10917afd228c5892541d94acc3d6814c8d73589c4050c779a921fab9c82" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport" version="4.1.115.Final">
<artifact name="netty-transport-4.1.115.Final.jar">
<sha256 value="c3d71faaa736ffd2c9260ab0b498024b814c39c7d764bea8113fa98de6e2bdd2" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-4.1.115.Final.pom">
<sha256 value="9677471c5409adced1f6cdb65a3ad8015e2e970990aba497a4eeca18abc363f9" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-classes-epoll" version="4.1.114.Final">
<artifact name="netty-transport-classes-epoll-4.1.114.Final.jar">
<sha256 value="a90b4277df568be0562e08271060a28870c57ba5a91fe792057f11e986fe777e" origin="Generated by Gradle"/>
@ -2210,6 +2428,14 @@
<sha256 value="66c775019d67b3a40a6880265b90dc88b01660c53db7ae2f65cfea5e74994715" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-classes-epoll" version="4.1.115.Final">
<artifact name="netty-transport-classes-epoll-4.1.115.Final.jar">
<sha256 value="40aa67b4463cca0ab346e393c87f6c37e8954d18ec8b78567d95b55aa1f2b3aa" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-classes-epoll-4.1.115.Final.pom">
<sha256 value="e57cc702f24b733565741ce3a69d89a2b5f5dcbda34c52b779fd02ba68c40987" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-classes-kqueue" version="4.1.114.Final">
<artifact name="netty-transport-classes-kqueue-4.1.114.Final.jar">
<sha256 value="8a07fed5985502dd68936f70b0dd5639d2e69c257c2300610936ce0e6da9847d" origin="Generated by Gradle"/>
@ -2218,6 +2444,14 @@
<sha256 value="90cbf66fe7c2a185aaf2dc28b0136f8ef8ba8eb51be1c319bcbd7f7372af09f5" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-classes-kqueue" version="4.1.115.Final">
<artifact name="netty-transport-classes-kqueue-4.1.115.Final.jar">
<sha256 value="77d3a0930f86870b48e668635e214e0c81205f90f2012dc70c8417b59a839d04" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-classes-kqueue-4.1.115.Final.pom">
<sha256 value="6e3d4260612e3e5af0fcd9042d20a9249f7f643c282906c34b2a568f7dea5e69" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-native-epoll" version="4.1.111.Final">
<artifact name="netty-transport-native-epoll-4.1.111.Final.pom">
<sha256 value="c14b3e677409871ae1cb80436dd06945591ae201ce3cc96db6a52957c7b9e574" origin="Generated by Gradle"/>
@ -2240,6 +2474,23 @@
<sha256 value="92d4dee865dc002fef64e19e602b6f6616667da22568869fb1135715a0344bf8" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-native-epoll" version="4.1.115.Final">
<artifact name="netty-transport-native-epoll-4.1.115.Final-linux-aarch_64.jar">
<sha256 value="82051543cbb328b5b45803229ccddf921f3e1897f9d75358ea76143a65a82e48" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-native-epoll-4.1.115.Final-linux-riscv64.jar">
<sha256 value="635298af6e7f9f1aac417a5a65c29da8e88d1d4fc176aa8b047107730ab49f83" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-native-epoll-4.1.115.Final-linux-x86_64.jar">
<sha256 value="f0ffa992e676025e2202643b3be490f595c19ca8f91031b7fde502e7874c2b55" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-native-epoll-4.1.115.Final.jar">
<sha256 value="9097c84e10f7fb81d10c72226d0fc4f85f4864b2ce8eb94e48561b679a06a8c3" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-native-epoll-4.1.115.Final.pom">
<sha256 value="0f2e546db040b7cbebd911dbdef0f897d7bf36b9cae9a53e047a49cb2c497b0c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-native-kqueue" version="4.1.111.Final">
<artifact name="netty-transport-native-kqueue-4.1.111.Final.pom">
<sha256 value="d1bf448ced9703e41e63f539f8523246f2a163434ddf4330d213262e731d5707" origin="Generated by Gradle"/>
@ -2259,6 +2510,20 @@
<sha256 value="0ca766af3bb08dfa44747c7cac67b408d5b6cc1fed051febc1b423edc077afb7" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-native-kqueue" version="4.1.115.Final">
<artifact name="netty-transport-native-kqueue-4.1.115.Final-osx-aarch_64.jar">
<sha256 value="bd71c4e8f14098057963a0342ba0ce2e39592d9558f1cd0cfdea81f9686901f0" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-native-kqueue-4.1.115.Final-osx-x86_64.jar">
<sha256 value="2ed228b9c42d4d139217abd64c944424a517b005887d705b8984a6e7fe5e6f92" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-native-kqueue-4.1.115.Final.jar">
<sha256 value="d97267348751c82da1ce12e901c2899243424d5264f047a1423ec3f22ea66ba4" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-native-kqueue-4.1.115.Final.pom">
<sha256 value="765e74114e7381fdcdd1b189d695b624113590f471980fd96745f1f2950014c5" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-native-unix-common" version="4.1.111.Final">
<artifact name="netty-transport-native-unix-common-4.1.111.Final.pom">
<sha256 value="2ea70a1864ab38fcec2bdc28c69ee9756dbad58a4626c664554d3c860d540981" origin="Generated by Gradle"/>
@ -2272,6 +2537,14 @@
<sha256 value="832b43c284e2c0cf0f57d62928fa72967b6aa6e5dc8766c6c9b2d01fddf7951d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-native-unix-common" version="4.1.115.Final">
<artifact name="netty-transport-native-unix-common-4.1.115.Final.jar">
<sha256 value="4b03e716272657c296b0204b57c140b2b2ca96b1a746c92da41f595892ec6d88" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-native-unix-common-4.1.115.Final.pom">
<sha256 value="96075271c578faadffec6f133991ea30884a69a41e07245a5ff8d5e7e5dd9f07" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-rxtx" version="4.1.114.Final">
<artifact name="netty-transport-rxtx-4.1.114.Final.jar">
<sha256 value="8927af869c006d73921d9db739d747f82fe5568c82ad8c1982fef954c5ecb63d" origin="Generated by Gradle"/>
@ -2280,6 +2553,14 @@
<sha256 value="b82852b37ecedf8342eeee3cd69aae7658e0ed485ef7c2b0f2ba384dd223dd17" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-rxtx" version="4.1.115.Final">
<artifact name="netty-transport-rxtx-4.1.115.Final.jar">
<sha256 value="33e80b3c468be74f448416d59edbf4618ea4917d697a3cbc4a53e13516bfd5ed" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-rxtx-4.1.115.Final.pom">
<sha256 value="38713e766cdf792a6d309adaba05193419a1ee8f1aea63a68cdabfe736bf5acd" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-sctp" version="4.1.114.Final">
<artifact name="netty-transport-sctp-4.1.114.Final.jar">
<sha256 value="5db192fb9c23615cf82862888c192f3ec98bae26410e1ac7ee40ecebe208e181" origin="Generated by Gradle"/>
@ -2288,6 +2569,14 @@
<sha256 value="95b0121474bc8938d7817cd969d345e04021cd77d60d7b3e9f5e875b426336bd" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-sctp" version="4.1.115.Final">
<artifact name="netty-transport-sctp-4.1.115.Final.jar">
<sha256 value="016e8596b4b2357c2671a8691cafaaab7650689d01715cda2a0b85631f22f3c6" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-sctp-4.1.115.Final.pom">
<sha256 value="844fdde08ab3dd22f5cac9e6f211f29a75caa8d80d986e5f5d459f95eab06d26" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-udt" version="4.1.114.Final">
<artifact name="netty-transport-udt-4.1.114.Final.jar">
<sha256 value="2431ecd15cde787019de5aa0a48063e6d72758ff75e67ed5d0009f470f559009" origin="Generated by Gradle"/>
@ -2296,6 +2585,14 @@
<sha256 value="faff00ad0c07c5316ce118b2a36276e03bb00feb2b86f4e80a351f417392cd1b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.netty" name="netty-transport-udt" version="4.1.115.Final">
<artifact name="netty-transport-udt-4.1.115.Final.jar">
<sha256 value="c505809dbb2d1b159eb1732dfa10c68f05da41ea9a479416690ff9a76908e4fb" origin="Generated by Gradle"/>
</artifact>
<artifact name="netty-transport-udt-4.1.115.Final.pom">
<sha256 value="71338f622075315979a0709b9b5952aa8fdb019b75500b5437abdefbd9e0e6f5" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.opencensus" name="opencensus-api" version="0.31.1">
<artifact name="opencensus-api-0.31.1.jar">
<sha256 value="f1474d47f4b6b001558ad27b952e35eda5cc7146788877fc52938c6eba24b382" origin="Generated by Gradle"/>

@ -40,7 +40,8 @@ public class MetricCategoryRegistryImpl implements MetricCategoryRegistry {
* @param categoryEnum the category enum
*/
public <T extends Enum<T> & MetricCategory> void addCategories(final Class<T> categoryEnum) {
EnumSet.allOf(categoryEnum).forEach(this::addMetricCategory);
EnumSet.allOf(categoryEnum)
.forEach(category -> metricCategories.put(category.name(), category));
}
/**

@ -28,7 +28,7 @@ javaPlatform {
dependencies {
api platform('com.fasterxml.jackson:jackson-bom:2.18.0')
api platform('io.grpc:grpc-bom:1.68.0')
api platform('io.netty:netty-bom:4.1.114.Final')
api platform('io.netty:netty-bom:4.1.115.Final')
api platform('io.opentelemetry:opentelemetry-bom:1.43.0')
api platform('io.prometheus:simpleclient_bom:0.16.0')
api platform('io.vertx:vertx-stack-depchain:4.5.10')

@ -264,7 +264,7 @@ public abstract class RocksDBColumnarKeyValueStorageTest extends AbstractKeyValu
List.of());
store.close();
// Create new db without ignoring experimental colum family will add column to db
// Create new db without ignoring experimental column family will add column to db
store =
createSegmentedStore(
testPath,

@ -25,7 +25,7 @@ public interface FuzzTarget {
/**
* The target to fuzz
*
* @param data data proviced by the fuzzer
* @param data data provided by the fuzzer
*/
void fuzz(byte[] data);
}

Loading…
Cancel
Save