Merge branch 'main' into bonsai-account-equals

pull/7845/head
Matt Whitehead 6 days ago committed by GitHub
commit 15b94a9d98
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 27
      .github/workflows/stale-issues.yml
  2. 3
      CHANGELOG.md
  3. 1
      MAINTAINERS.md
  4. 2
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java
  5. 2
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java
  6. 2
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.java
  7. 1
      besu/build.gradle
  8. 2
      besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java
  9. 52
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  10. 14
      besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java
  11. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/ApiConfigurationOptions.java
  12. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/ChainPruningOptions.java
  13. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/DnsOptions.java
  14. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/EngineRPCConfiguration.java
  15. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/EngineRPCOptions.java
  16. 4
      besu/src/main/java/org/hyperledger/besu/cli/options/EthProtocolOptions.java
  17. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/EthstatsOptions.java
  18. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/EvmOptions.java
  19. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/GraphQlOptions.java
  20. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/InProcessRpcOptions.java
  21. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/IpcOptions.java
  22. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/JsonRpcHttpOptions.java
  23. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/LoggingLevelOption.java
  24. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/MetricsOptions.java
  25. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/NatOptions.java
  26. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/NativeLibraryOptions.java
  27. 4
      besu/src/main/java/org/hyperledger/besu/cli/options/NetworkingOptions.java
  28. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/NodePrivateKeyFileOption.java
  29. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/P2PDiscoveryOptions.java
  30. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/P2PTLSConfigOptions.java
  31. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/PermissionsOptions.java
  32. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/PluginsConfigurationOptions.java
  33. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/PrivacyPluginOptions.java
  34. 2
      besu/src/main/java/org/hyperledger/besu/cli/options/RPCOptions.java
  35. 135
      besu/src/main/java/org/hyperledger/besu/cli/options/RpcWebsocketOptions.java
  36. 4
      besu/src/main/java/org/hyperledger/besu/cli/options/SynchronizerOptions.java
  37. 2
      besu/src/main/java/org/hyperledger/besu/cli/subcommands/PublicKeySubCommand.java
  38. 4
      besu/src/main/java/org/hyperledger/besu/components/BesuCommandModule.java
  39. 28
      besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java
  40. 1
      besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java
  41. 2
      besu/src/main/java/org/hyperledger/besu/services/BesuConfigurationImpl.java
  42. 24
      besu/src/main/scripts/unixStartScript.txt
  43. 12
      besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
  44. 8
      besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java
  45. 1
      besu/src/test/java/org/hyperledger/besu/cli/options/EthProtocolOptionsTest.java
  46. 2
      besu/src/test/java/org/hyperledger/besu/cli/options/LoggingLevelOptionTest.java
  47. 25
      besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java
  48. 1
      besu/src/test/java/org/hyperledger/besu/cli/options/NetworkingOptionsTest.java
  49. 1
      besu/src/test/java/org/hyperledger/besu/cli/options/SynchronizerOptionsTest.java
  50. 2
      besu/src/test/java/org/hyperledger/besu/cli/util/ConfigDefaultValueProviderStrategyTest.java
  51. 13
      besu/src/test/resources/everything_config.toml
  52. 3
      build.gradle
  53. 4
      config/src/main/java/org/hyperledger/besu/config/GenesisReader.java
  54. 15
      config/src/test/java/org/hyperledger/besu/config/GenesisReaderTest.java
  55. 2
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java
  56. 2
      docs/Private-Txns-Migration.md
  57. 2
      docs/trace_rpc_apis.md
  58. 123
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHead.java
  59. 112
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketConfiguration.java
  60. 72
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketService.java
  61. 198
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHeadTest.java
  62. 444
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceTLSTest.java
  63. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java
  64. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ProtocolContext.java
  65. 15
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java
  66. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/forest/ForestWorldStateArchive.java
  67. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/WorldStateArchive.java
  68. 1
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java
  69. 5
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java
  70. 39
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/WorldStateHealerHelper.java
  71. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java
  72. 4
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java
  73. 22
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProviderTest.java
  74. 7
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java
  75. 6
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java
  76. 8
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionBroadcaster.java
  77. 1
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
  78. 5
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerGetAccountRangeTest.java
  79. 12
      evm/src/main/java/org/hyperledger/besu/evm/operation/PushOperation.java
  80. 83
      evm/src/test/java/org/hyperledger/besu/evm/operation/PushOperationTest.java
  81. 297
      gradle/verification-metadata.xml
  82. 3
      metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImpl.java
  83. 13
      platform/build.gradle
  84. 2
      plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorageTest.java
  85. 1
      settings.gradle
  86. 2
      testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/FuzzTarget.java

@ -0,0 +1,27 @@
name: Close inactive issues
on:
schedule:
- cron: "30 1 * * *"
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
contents: write
steps:
- uses: actions/stale@v5
with:
days-before-issue-stale: 180
days-before-issue-close: 14
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 6 months with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
days-before-pr-stale: 30
days-before-pr-close: 14
stale-pr-message: "This pr is stale because it has been open for 30 days with no activity."
close-pr-message: "This pr was closed because it has been inactive for 14 days since being marked as stale."
remove-issue-stale-when-updated: true
remove-pr-stale-when-updated: true
repo-token: ${{ secrets.GITHUB_TOKEN }}

@ -10,6 +10,7 @@
### Additions and Improvements ### 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) - 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) - 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) - 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) - 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 ### Bug fixes
- Fix registering new metric categories from plugins [#7825](https://github.com/hyperledger/besu/pull/7825) - 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 ## 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) - Remove long-deprecated `perm*whitelist*` methods [#7401](https://github.com/hyperledger/besu/pull/7401)
### Additions and Improvements ### 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) - 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) - 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) - 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 | | Luis Pinto | lu-pinto | lu-pinto |
| Lucas Saldanha | lucassaldanha | lucassaldanha | | Lucas Saldanha | lucassaldanha | lucassaldanha |
| Sally MacFarlane | macfarla | macfarla | | Sally MacFarlane | macfarla | macfarla |
| Matilda Clerke | Matilda-Clerke | MatildaClerke |
| Karim Taam | matkt | matkt | | Karim Taam | matkt | matkt |
| Matthew Whitehead| matthew1001 | matthew.whitehead | | Matthew Whitehead| matthew1001 | matthew.whitehead |
| Meredith Baxter | mbaxter | mbaxter | | Meredith Baxter | mbaxter | mbaxter |

@ -17,9 +17,9 @@ package org.hyperledger.besu.tests.acceptance.dsl.node;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import org.hyperledger.besu.cli.options.NetworkingOptions;
import org.hyperledger.besu.cli.options.TransactionPoolOptions; import org.hyperledger.besu.cli.options.TransactionPoolOptions;
import org.hyperledger.besu.cli.options.storage.DataStorageOptions; import org.hyperledger.besu.cli.options.storage.DataStorageOptions;
import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration;

@ -494,6 +494,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
final RpcEndpointServiceImpl rpcEndpointServiceImpl, final RpcEndpointServiceImpl rpcEndpointServiceImpl,
final BesuConfiguration commonPluginConfiguration, final BesuConfiguration commonPluginConfiguration,
final PermissioningServiceImpl permissioningService, final PermissioningServiceImpl permissioningService,
final MetricsConfiguration metricsConfiguration,
final MetricCategoryRegistryImpl metricCategoryRegistry, final MetricCategoryRegistryImpl metricCategoryRegistry,
final MetricsSystem metricsSystem, final MetricsSystem metricsSystem,
final @Named("ExtraCLIOptions") List<String> extraCLIOptions, final @Named("ExtraCLIOptions") List<String> extraCLIOptions,
@ -512,6 +513,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
TransactionSimulationService.class, transactionSimulationServiceImpl); TransactionSimulationService.class, transactionSimulationServiceImpl);
besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl); besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl);
besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration);
metricCategoryRegistry.setMetricsConfiguration(metricsConfiguration);
besuPluginContext.addService(MetricCategoryRegistry.class, metricCategoryRegistry); besuPluginContext.addService(MetricCategoryRegistry.class, metricCategoryRegistry);
besuPluginContext.addService(MetricsSystem.class, metricsSystem); besuPluginContext.addService(MetricsSystem.class, metricsSystem);

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

@ -49,7 +49,6 @@ dependencies {
implementation project(':ethereum:eth') implementation project(':ethereum:eth')
implementation project(':ethereum:p2p') implementation project(':ethereum:p2p')
implementation project(':ethereum:permissioning') implementation project(':ethereum:permissioning')
implementation project(':ethereum:retesteth')
implementation project(':ethereum:rlp') implementation project(':ethereum:rlp')
implementation project(':ethereum:trie') implementation project(':ethereum:trie')
implementation project(':ethereum:stratum') implementation project(':ethereum:stratum')

@ -23,7 +23,7 @@ import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIV
import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.cli.options.stable.EthstatsOptions; import org.hyperledger.besu.cli.options.EthstatsOptions;
import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKey;
import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.ProtocolContext;

@ -40,36 +40,36 @@ import org.hyperledger.besu.cli.config.ProfilesCompletionCandidates;
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty;
import org.hyperledger.besu.cli.error.BesuExecutionExceptionHandler; import org.hyperledger.besu.cli.error.BesuExecutionExceptionHandler;
import org.hyperledger.besu.cli.error.BesuParameterExceptionHandler; import org.hyperledger.besu.cli.error.BesuParameterExceptionHandler;
import org.hyperledger.besu.cli.options.ApiConfigurationOptions;
import org.hyperledger.besu.cli.options.ChainPruningOptions;
import org.hyperledger.besu.cli.options.DnsOptions;
import org.hyperledger.besu.cli.options.EngineRPCConfiguration;
import org.hyperledger.besu.cli.options.EngineRPCOptions;
import org.hyperledger.besu.cli.options.EthProtocolOptions;
import org.hyperledger.besu.cli.options.EthstatsOptions;
import org.hyperledger.besu.cli.options.EvmOptions;
import org.hyperledger.besu.cli.options.GraphQlOptions;
import org.hyperledger.besu.cli.options.InProcessRpcOptions;
import org.hyperledger.besu.cli.options.IpcOptions;
import org.hyperledger.besu.cli.options.JsonRpcHttpOptions;
import org.hyperledger.besu.cli.options.LoggingLevelOption;
import org.hyperledger.besu.cli.options.MetricsOptions;
import org.hyperledger.besu.cli.options.MiningOptions; import org.hyperledger.besu.cli.options.MiningOptions;
import org.hyperledger.besu.cli.options.NatOptions;
import org.hyperledger.besu.cli.options.NativeLibraryOptions;
import org.hyperledger.besu.cli.options.NetworkingOptions;
import org.hyperledger.besu.cli.options.NodePrivateKeyFileOption;
import org.hyperledger.besu.cli.options.P2PDiscoveryOptions;
import org.hyperledger.besu.cli.options.P2PTLSConfigOptions;
import org.hyperledger.besu.cli.options.PermissionsOptions;
import org.hyperledger.besu.cli.options.PluginsConfigurationOptions;
import org.hyperledger.besu.cli.options.PrivacyPluginOptions;
import org.hyperledger.besu.cli.options.RPCOptions;
import org.hyperledger.besu.cli.options.RpcWebsocketOptions;
import org.hyperledger.besu.cli.options.SynchronizerOptions;
import org.hyperledger.besu.cli.options.TransactionPoolOptions; import org.hyperledger.besu.cli.options.TransactionPoolOptions;
import org.hyperledger.besu.cli.options.stable.ApiConfigurationOptions;
import org.hyperledger.besu.cli.options.stable.EngineRPCConfiguration;
import org.hyperledger.besu.cli.options.stable.EngineRPCOptions;
import org.hyperledger.besu.cli.options.stable.EthstatsOptions;
import org.hyperledger.besu.cli.options.stable.GraphQlOptions;
import org.hyperledger.besu.cli.options.stable.JsonRpcHttpOptions;
import org.hyperledger.besu.cli.options.stable.LoggingLevelOption;
import org.hyperledger.besu.cli.options.stable.MetricsOptions;
import org.hyperledger.besu.cli.options.stable.NodePrivateKeyFileOption;
import org.hyperledger.besu.cli.options.stable.P2PDiscoveryOptions;
import org.hyperledger.besu.cli.options.stable.PermissionsOptions;
import org.hyperledger.besu.cli.options.stable.PluginsConfigurationOptions;
import org.hyperledger.besu.cli.options.stable.RpcWebsocketOptions;
import org.hyperledger.besu.cli.options.storage.DataStorageOptions; import org.hyperledger.besu.cli.options.storage.DataStorageOptions;
import org.hyperledger.besu.cli.options.storage.DiffBasedSubStorageOptions; import org.hyperledger.besu.cli.options.storage.DiffBasedSubStorageOptions;
import org.hyperledger.besu.cli.options.unstable.ChainPruningOptions;
import org.hyperledger.besu.cli.options.unstable.DnsOptions;
import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions;
import org.hyperledger.besu.cli.options.unstable.EvmOptions;
import org.hyperledger.besu.cli.options.unstable.InProcessRpcOptions;
import org.hyperledger.besu.cli.options.unstable.IpcOptions;
import org.hyperledger.besu.cli.options.unstable.NatOptions;
import org.hyperledger.besu.cli.options.unstable.NativeLibraryOptions;
import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
import org.hyperledger.besu.cli.options.unstable.P2PTLSConfigOptions;
import org.hyperledger.besu.cli.options.unstable.PrivacyPluginOptions;
import org.hyperledger.besu.cli.options.unstable.RPCOptions;
import org.hyperledger.besu.cli.options.unstable.SynchronizerOptions;
import org.hyperledger.besu.cli.presynctasks.PreSynchronizationTaskRunner; import org.hyperledger.besu.cli.presynctasks.PreSynchronizationTaskRunner;
import org.hyperledger.besu.cli.presynctasks.PrivateDatabaseMigrationPreSyncTask; import org.hyperledger.besu.cli.presynctasks.PrivateDatabaseMigrationPreSyncTask;
import org.hyperledger.besu.cli.subcommands.PasswordSubCommand; import org.hyperledger.besu.cli.subcommands.PasswordSubCommand;

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

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;

@ -12,9 +12,8 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.ethereum.chain.ChainPrunerConfiguration; import org.hyperledger.besu.ethereum.chain.ChainPrunerConfiguration;
import org.hyperledger.besu.util.number.PositiveNumber; import org.hyperledger.besu.util.number.PositiveNumber;

@ -12,9 +12,8 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.ethereum.p2p.peers.EnodeDnsConfiguration; import org.hyperledger.besu.ethereum.p2p.peers.EnodeDnsConfiguration;
import org.hyperledger.besu.ethereum.p2p.peers.ImmutableEnodeDnsConfiguration; import org.hyperledger.besu.ethereum.p2p.peers.ImmutableEnodeDnsConfiguration;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty;

@ -12,13 +12,12 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_ENGINE_JSON_RPC_PORT; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_ENGINE_JSON_RPC_PORT;
import org.hyperledger.besu.cli.DefaultCommandValues; import org.hyperledger.besu.cli.DefaultCommandValues;
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.util.CommandLineUtils; import org.hyperledger.besu.cli.util.CommandLineUtils;
import java.nio.file.Path; import java.nio.file.Path;

@ -12,10 +12,8 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.options.OptionParser;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.hyperledger.besu.util.number.PositiveNumber; import org.hyperledger.besu.util.number.PositiveNumber;

@ -12,9 +12,8 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.ethstats.util.EthStatsConnectOptions; import org.hyperledger.besu.ethstats.util.EthStatsConnectOptions;
import java.nio.file.Path; import java.nio.file.Path;

@ -12,9 +12,8 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import java.util.List; import java.util.List;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration.DEFAULT_GRAPHQL_HTTP_PORT; import static org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration.DEFAULT_GRAPHQL_HTTP_PORT;

@ -12,12 +12,11 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import static org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_APIS; import static org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_APIS;
import static org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_ENABLED; import static org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_ENABLED;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.util.CommandLineUtils; import org.hyperledger.besu.cli.util.CommandLineUtils;
import org.hyperledger.besu.ethereum.api.jsonrpc.ImmutableInProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.ImmutableInProcessRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_JSON_RPC_HOST; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_JSON_RPC_HOST;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static java.util.stream.Collectors.toUnmodifiableSet; import static java.util.stream.Collectors.toUnmodifiableSet;
@ -24,7 +24,6 @@ import static org.hyperledger.besu.metrics.MetricsProtocol.PROMETHEUS;
import static org.hyperledger.besu.metrics.prometheus.MetricsConfiguration.DEFAULT_METRICS_PORT; import static org.hyperledger.besu.metrics.prometheus.MetricsConfiguration.DEFAULT_METRICS_PORT;
import static org.hyperledger.besu.metrics.prometheus.MetricsConfiguration.DEFAULT_METRICS_PUSH_PORT; import static org.hyperledger.besu.metrics.prometheus.MetricsConfiguration.DEFAULT_METRICS_PUSH_PORT;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.util.CommandLineUtils; import org.hyperledger.besu.cli.util.CommandLineUtils;
import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl; import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl;
import org.hyperledger.besu.metrics.MetricsProtocol; import org.hyperledger.besu.metrics.MetricsProtocol;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER; import static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import picocli.CommandLine; import picocli.CommandLine;

@ -12,10 +12,8 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.options.OptionParser;
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import java.util.Arrays; import java.util.Arrays;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_PATH_FORMAT_HELP; import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_PATH_FORMAT_HELP;

@ -12,12 +12,11 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.DefaultCommandValues; import org.hyperledger.besu.cli.DefaultCommandValues;
import org.hyperledger.besu.cli.converter.PercentageConverter; import org.hyperledger.besu.cli.converter.PercentageConverter;
import org.hyperledger.besu.cli.converter.SubnetInfoConverter; import org.hyperledger.besu.cli.converter.SubnetInfoConverter;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.util.CommandLineUtils; import org.hyperledger.besu.cli.util.CommandLineUtils;
import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration; import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration;
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_KEYSTORE_TYPE; import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_KEYSTORE_TYPE;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.DefaultCommandValues; import org.hyperledger.besu.cli.DefaultCommandValues;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;

@ -12,14 +12,13 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_CONTINUE_ON_PLUGIN_ERROR_OPTION_NAME; import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_CONTINUE_ON_PLUGIN_ERROR_OPTION_NAME;
import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME; import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME;
import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_PLUGINS_OPTION_NAME; import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_PLUGINS_OPTION_NAME;
import org.hyperledger.besu.cli.converter.PluginInfoConverter; import org.hyperledger.besu.cli.converter.PluginInfoConverter;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.util.CommandLineUtils; import org.hyperledger.besu.cli.util.CommandLineUtils;
import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration; import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration;
import org.hyperledger.besu.ethereum.core.plugins.PluginInfo; import org.hyperledger.besu.ethereum.core.plugins.PluginInfo;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import static picocli.CommandLine.Option; import static picocli.CommandLine.Option;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.ethereum.api.handlers.TimeoutOptions; import org.hyperledger.besu.ethereum.api.handlers.TimeoutOptions;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.VALID_APIS; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.VALID_APIS;
@ -120,6 +120,71 @@ public class RpcWebsocketOptions {
arity = "1") arity = "1")
private final File rpcWsAuthenticationPublicKeyFile = null; 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. */ /** Default Constructor. */
public RpcWebsocketOptions() {} public RpcWebsocketOptions() {}
@ -184,7 +249,61 @@ public class RpcWebsocketOptions {
"--rpc-ws-authentication-enabled", "--rpc-ws-authentication-enabled",
"--rpc-ws-authentication-credentials-file", "--rpc-ws-authentication-credentials-file",
"--rpc-ws-authentication-public-key-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) { if (isRpcWsAuthenticationEnabled) {
CommandLineUtils.checkOptionDependencies( CommandLineUtils.checkOptionDependencies(
@ -222,6 +341,18 @@ public class RpcWebsocketOptions {
webSocketConfiguration.setAuthenticationPublicKeyFile(rpcWsAuthenticationPublicKeyFile); webSocketConfiguration.setAuthenticationPublicKeyFile(rpcWsAuthenticationPublicKeyFile);
webSocketConfiguration.setAuthenticationAlgorithm(rpcWebsocketsAuthenticationAlgorithm); webSocketConfiguration.setAuthenticationAlgorithm(rpcWebsocketsAuthenticationAlgorithm);
webSocketConfiguration.setTimeoutSec(wsTimoutSec); 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; return webSocketConfiguration;
} }

@ -12,10 +12,8 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.unstable; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.options.OptionParser;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.snapsync.ImmutableSnapSyncConfiguration; import org.hyperledger.besu.ethereum.eth.sync.snapsync.ImmutableSnapSyncConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.snapsync.SnapSyncConfiguration; import org.hyperledger.besu.ethereum.eth.sync.snapsync.SnapSyncConfiguration;

@ -20,7 +20,7 @@ import static org.hyperledger.besu.cli.subcommands.PublicKeySubCommand.COMMAND_N
import org.hyperledger.besu.cli.BesuCommand; import org.hyperledger.besu.cli.BesuCommand;
import org.hyperledger.besu.cli.DefaultCommandValues; import org.hyperledger.besu.cli.DefaultCommandValues;
import org.hyperledger.besu.cli.options.stable.NodePrivateKeyFileOption; import org.hyperledger.besu.cli.options.NodePrivateKeyFileOption;
import org.hyperledger.besu.cli.subcommands.PublicKeySubCommand.AddressSubCommand; import org.hyperledger.besu.cli.subcommands.PublicKeySubCommand.AddressSubCommand;
import org.hyperledger.besu.cli.subcommands.PublicKeySubCommand.ExportSubCommand; import org.hyperledger.besu.cli.subcommands.PublicKeySubCommand.ExportSubCommand;
import org.hyperledger.besu.cli.util.VersionProvider; import org.hyperledger.besu.cli.util.VersionProvider;

@ -20,8 +20,8 @@ import org.hyperledger.besu.chainexport.RlpBlockExporter;
import org.hyperledger.besu.chainimport.JsonBlockImporter; import org.hyperledger.besu.chainimport.JsonBlockImporter;
import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.chainimport.RlpBlockImporter;
import org.hyperledger.besu.cli.BesuCommand; import org.hyperledger.besu.cli.BesuCommand;
import org.hyperledger.besu.cli.options.stable.P2PDiscoveryOptions; import org.hyperledger.besu.cli.options.P2PDiscoveryOptions;
import org.hyperledger.besu.cli.options.unstable.RPCOptions; import org.hyperledger.besu.cli.options.RPCOptions;
import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration; import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;

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

@ -132,6 +132,7 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder {
genesisConfigOptions, genesisConfigOptions,
forksSchedule, forksSchedule,
nodeKey, nodeKey,
privacyParameters,
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningConfiguration, miningConfiguration,

@ -14,7 +14,7 @@
*/ */
package org.hyperledger.besu.services; package org.hyperledger.besu.services;
import org.hyperledger.besu.cli.options.stable.JsonRpcHttpOptions; import org.hyperledger.besu.cli.options.JsonRpcHttpOptions;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.MiningConfiguration; import org.hyperledger.besu.ethereum.core.MiningConfiguration;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;

@ -182,19 +182,19 @@ APP_ARGS=`save "\$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules # 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" 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 [ "\$darwin" = "false" -a "\$msys" = "false" ]; then
# check if jemalloc is available if [ "\$BESU_USING_JEMALLOC" != "FALSE" -a "\$BESU_USING_JEMALLOC" != "false" ]; then
TEST_JEMALLOC=\$(LD_PRELOAD=libjemalloc.so sh -c true 2>&1) # 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 # if jemalloc is available the output is empty, otherwise the output has an error line
export LD_PRELOAD=libjemalloc.so if [ -z "\$TEST_JEMALLOC" ]; then
export BESU_USING_JEMALLOC=true export LD_PRELOAD=libjemalloc.so
else else
# jemalloc not available, as fallback limit malloc to 2 arenas # jemalloc not available, as fallback limit malloc to 2 arenas
export MALLOC_ARENA_MAX=2 export MALLOC_ARENA_MAX=2
fi fi
fi
fi fi
exec "\$JAVACMD" "\$@" exec "\$JAVACMD" "\$@"

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

@ -34,13 +34,13 @@ import org.hyperledger.besu.chainexport.RlpBlockExporter;
import org.hyperledger.besu.chainimport.JsonBlockImporter; import org.hyperledger.besu.chainimport.JsonBlockImporter;
import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.chainimport.RlpBlockImporter;
import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.options.EthProtocolOptions;
import org.hyperledger.besu.cli.options.EthstatsOptions;
import org.hyperledger.besu.cli.options.MiningOptions; import org.hyperledger.besu.cli.options.MiningOptions;
import org.hyperledger.besu.cli.options.NetworkingOptions;
import org.hyperledger.besu.cli.options.SynchronizerOptions;
import org.hyperledger.besu.cli.options.TransactionPoolOptions; import org.hyperledger.besu.cli.options.TransactionPoolOptions;
import org.hyperledger.besu.cli.options.stable.EthstatsOptions;
import org.hyperledger.besu.cli.options.storage.DataStorageOptions; import org.hyperledger.besu.cli.options.storage.DataStorageOptions;
import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions;
import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
import org.hyperledger.besu.cli.options.unstable.SynchronizerOptions;
import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuController;

@ -18,7 +18,6 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoInteractions;
import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;

@ -12,7 +12,7 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
package org.hyperledger.besu.cli.options.stable; package org.hyperledger.besu.cli.options;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;

@ -14,13 +14,18 @@
*/ */
package org.hyperledger.besu.cli.options; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.stable.MetricsOptions; import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.metrics.BesuMetricCategory;
import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl; import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl;
import org.hyperledger.besu.metrics.StandardMetricCategory; import org.hyperledger.besu.metrics.StandardMetricCategory;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; 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.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
@ -65,4 +70,22 @@ public class MetricsOptionsTest
protected String[] getNonOptionFields() { protected String[] getNonOptionFields() {
return new String[] {"metricCategoryRegistry"}; 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(",")));
}
} }

@ -17,7 +17,6 @@ package org.hyperledger.besu.cli.options;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import java.util.Arrays; import java.util.Arrays;

@ -14,7 +14,6 @@
*/ */
package org.hyperledger.besu.cli.options; package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.unstable.SynchronizerOptions;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.snapsync.ImmutableSnapSyncConfiguration; import org.hyperledger.besu.ethereum.eth.sync.snapsync.ImmutableSnapSyncConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.snapsync.SnapSyncConfiguration; import org.hyperledger.besu.ethereum.eth.sync.snapsync.SnapSyncConfiguration;

@ -25,7 +25,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.hyperledger.besu.cli.error.BesuParameterExceptionHandler; import org.hyperledger.besu.cli.error.BesuParameterExceptionHandler;
import org.hyperledger.besu.cli.options.stable.LoggingLevelOption; import org.hyperledger.besu.cli.options.LoggingLevelOption;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;

@ -120,6 +120,19 @@ rpc-ws-max-frame-size=65535
rpc-ws-authentication-enabled=false rpc-ws-authentication-enabled=false
rpc-ws-authentication-credentials-file="none" rpc-ws-authentication-credentials-file="none"
rpc-ws-authentication-jwt-public-key-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
api-gas-price-blocks=100 api-gas-price-blocks=100

@ -417,9 +417,6 @@ configure(allprojects - project(':platform')) {
'-org.hyperledger.besu.ethereum.permissioning.*,' + '-org.hyperledger.besu.ethereum.permissioning.*,' +
// referencetests module // referencetests module
'-org.hyperledger.besu.ethereum.referencetests,' + '-org.hyperledger.besu.ethereum.referencetests,' +
// retesteth module
'-org.hyperledger.besu.ethereum.retesteth.methods,' +
'-org.hyperledger.besu.ethereum.retesteth,' +
//rlp module //rlp module
'-org.hyperledger.besu.ethereum.rlp,' + '-org.hyperledger.besu.ethereum.rlp,' +
// stratum module // stratum module

@ -80,7 +80,9 @@ interface GenesisReader {
final var on = normalizeKeys((ObjectNode) entry.getValue()); final var on = normalizeKeys((ObjectNode) entry.getValue());
return new GenesisAccount( return new GenesisAccount(
Address.fromHexString(entry.getKey()), Address.fromHexString(entry.getKey()),
JsonUtil.getString(on, "nonce").map(ParserUtils::parseUnsignedLong).orElse(0L), JsonUtil.getValueAsString(on, "nonce")
.map(ParserUtils::parseUnsignedLong)
.orElse(0L),
JsonUtil.getString(on, "balance") JsonUtil.getString(on, "balance")
.map(ParserUtils::parseBalance) .map(ParserUtils::parseBalance)
.orElse(Wei.ZERO), .orElse(Wei.ZERO),

@ -17,6 +17,7 @@ package org.hyperledger.besu.config;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.config.GenesisReader.ALLOCATION_FIELD; import static org.hyperledger.besu.config.GenesisReader.ALLOCATION_FIELD;
import static org.hyperledger.besu.config.GenesisReader.CONFIG_FIELD; import static org.hyperledger.besu.config.GenesisReader.CONFIG_FIELD;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
@ -27,6 +28,7 @@ import java.nio.file.Path;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.io.TempDir;
@ -111,4 +113,17 @@ public class GenesisReaderTest {
entry.put("balance", balance.toShortHexString()); entry.put("balance", balance.toShortHexString());
return entry; return entry;
} }
@Test
void testNonceHandlingAsStringAndInteger() {
ObjectNode accountNode = JsonNodeFactory.instance.objectNode();
accountNode.put("nonce", 10);
String nonceAsStringFromInt = JsonUtil.getValueAsString(accountNode, "nonce").orElse("");
assertEquals("10", nonceAsStringFromInt, "Nonce should convert integer to string correctly");
accountNode.put("nonce", "20");
String nonceAsStringDirect = JsonUtil.getValueAsString(accountNode, "nonce").orElse("");
assertEquals("20", nonceAsStringDirect, "Nonce should keep string as string correctly");
}
} }

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

@ -12,7 +12,7 @@ state storage when upgrading to v1.4. It is not possible to upgrade to v1.4 with
## Private transactions created using v1.3.4 or earlier ## Private transactions created using v1.3.4 or earlier
A critical issue for privacy users with private transactions created using Hyperledger Besu v1.3.4 A critical issue for privacy users with private transactions created using Hyperledger Besu v1.3.4
or earlier has been identified. If you have a network with private transaction created using v1.3.4 or earlier has been identified. If you have a network with private transactions created using v1.3.4
or earlier, please read the following and take the appropriate steps: or earlier, please read the following and take the appropriate steps:
https://wiki.hyperledger.org/display/BESU/Critical+Issue+for+Privacy+Users https://wiki.hyperledger.org/display/BESU/Critical+Issue+for+Privacy+Users

@ -16,7 +16,7 @@ implementations of Besu might track gas refunds separately.
### Returned Memory from Calls ### 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 from a `RETURN` opcode. Other implementations return the contents of the
reserved output space for the call operations. Note two major differences: reserved output space for the call operations. Note two major differences:

@ -21,22 +21,41 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.trie.diffbased.common.DiffBasedWorldStateProvider;
import java.util.Optional; import java.util.Optional;
public class DebugSetHead extends AbstractBlockParameterMethod { import graphql.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DebugSetHead extends AbstractBlockParameterOrBlockHashMethod {
private final ProtocolContext protocolContext; private final ProtocolContext protocolContext;
private static final Logger LOG = LoggerFactory.getLogger(DebugSetHead.class);
private static final int DEFAULT_MAX_TRIE_LOGS_TO_ROLL_AT_ONCE = 512;
private final long maxTrieLogsToRollAtOnce;
public DebugSetHead(final BlockchainQueries blockchain, final ProtocolContext protocolContext) { public DebugSetHead(final BlockchainQueries blockchain, final ProtocolContext protocolContext) {
super(blockchain); this(blockchain, protocolContext, DEFAULT_MAX_TRIE_LOGS_TO_ROLL_AT_ONCE);
}
@VisibleForTesting
DebugSetHead(
final BlockchainQueries blockchain,
final ProtocolContext protocolContext,
final long maxTrieLogsToRollAtOnce) {
super(blockchain);
this.protocolContext = protocolContext; this.protocolContext = protocolContext;
this.maxTrieLogsToRollAtOnce = Math.abs(maxTrieLogsToRollAtOnce);
} }
@Override @Override
@ -45,26 +64,108 @@ public class DebugSetHead extends AbstractBlockParameterMethod {
} }
@Override @Override
protected BlockParameter blockParameter(final JsonRpcRequestContext request) { protected BlockParameterOrBlockHash blockParameterOrBlockHash(
final JsonRpcRequestContext requestContext) {
try { try {
return request.getRequiredParameter(0, BlockParameter.class); return requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class);
} catch (JsonRpcParameterException e) { } catch (JsonRpcParameterException e) {
throw new InvalidJsonRpcParameters( throw new InvalidJsonRpcParameters(
"Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); "Invalid block or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e);
} }
} }
@Override @Override
protected Object resultByBlockNumber( protected Object resultByBlockHash(final JsonRpcRequestContext request, final Hash blockHash) {
final JsonRpcRequestContext request, final long blockNumber) { var blockchainQueries = getBlockchainQueries();
final Optional<Hash> maybeBlockHash = getBlockchainQueries().getBlockHashByNumber(blockNumber); var blockchain = protocolContext.getBlockchain();
Optional<BlockHeader> maybeBlockHeader = blockchainQueries.getBlockHeaderByHash(blockHash);
Optional<Boolean> maybeMoveWorldstate = shouldMoveWorldstate(request);
if (maybeBlockHash.isEmpty()) { if (maybeBlockHeader.isEmpty()) {
return new JsonRpcErrorResponse(request.getRequest().getId(), UNKNOWN_BLOCK); return new JsonRpcErrorResponse(request.getRequest().getId(), UNKNOWN_BLOCK);
} }
protocolContext.getBlockchain().rewindToBlock(maybeBlockHash.get()); // Optionally move the worldstate to the specified blockhash, if it is present in the chain
if (maybeMoveWorldstate.orElse(Boolean.FALSE)) {
var archive = blockchainQueries.getWorldStateArchive();
// Only DiffBasedWorldState's need to be moved:
if (archive instanceof DiffBasedWorldStateProvider diffBasedArchive) {
if (rollIncrementally(maybeBlockHeader.get(), blockchain, diffBasedArchive)) {
return JsonRpcSuccessResponse.SUCCESS_RESULT;
}
}
}
// If we are not rolling incrementally or if there was an error incrementally rolling,
// move the blockchain to the requested hash:
blockchain.rewindToBlock(maybeBlockHeader.get().getBlockHash());
return JsonRpcSuccessResponse.SUCCESS_RESULT; return JsonRpcSuccessResponse.SUCCESS_RESULT;
} }
private boolean rollIncrementally(
final BlockHeader target,
final MutableBlockchain blockchain,
final DiffBasedWorldStateProvider archive) {
try {
if (archive.isWorldStateAvailable(target.getStateRoot(), target.getBlockHash())) {
// WARNING, this can be dangerous for a DiffBasedWorldstate if a concurrent
// process attempts to move or modify the head worldstate.
// Ensure no block processing is occuring when using this feature.
// No engine-api, block import, sync, mining or other rpc calls should be running.
Optional<BlockHeader> currentHead =
archive
.getWorldStateKeyValueStorage()
.getWorldStateBlockHash()
.flatMap(blockchain::getBlockHeader);
while (currentHead.isPresent()
&& !target.getStateRoot().equals(currentHead.get().getStateRoot())) {
long delta = currentHead.get().getNumber() - target.getNumber();
if (maxTrieLogsToRollAtOnce < Math.abs(delta)) {
// do we need to move forward or backward?
long distanceToMove = (delta > 0) ? -maxTrieLogsToRollAtOnce : maxTrieLogsToRollAtOnce;
// Add distanceToMove to the current block number to get the interim target header
var interimHead =
blockchain.getBlockHeader(currentHead.get().getNumber() + distanceToMove);
interimHead.ifPresent(
it -> {
blockchain.rewindToBlock(it.getBlockHash());
archive.getMutable(it.getStateRoot(), it.getBlockHash());
LOG.info("incrementally rolled worldstate to {}", it.toLogString());
});
currentHead = interimHead;
} else {
blockchain.rewindToBlock(target.getBlockHash());
archive.getMutable(target.getStateRoot(), target.getBlockHash());
currentHead = Optional.of(target);
LOG.info("finished rolling worldstate to {}", target.toLogString());
}
}
}
return true;
} catch (Exception ex) {
LOG.error("Failed to incrementally roll blockchain to " + target.toLogString(), ex);
return false;
}
}
private Optional<Boolean> shouldMoveWorldstate(final JsonRpcRequestContext request) {
try {
return request.getOptionalParameter(1, Boolean.class);
} catch (JsonRpcParameterException e) {
throw new InvalidJsonRpcParameters(
"Invalid should move worldstate boolean parameter (index 1)",
RpcErrorType.INVALID_PARAMS,
e);
}
}
} }

@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
@ -49,6 +50,21 @@ public class WebSocketConfiguration {
private int maxActiveConnections; private int maxActiveConnections;
private int maxFrameSize; 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() { public static WebSocketConfiguration createDefault() {
final WebSocketConfiguration config = new WebSocketConfiguration(); final WebSocketConfiguration config = new WebSocketConfiguration();
config.setEnabled(false); config.setEnabled(false);
@ -159,6 +175,102 @@ public class WebSocketConfiguration {
this.timeoutSec = timeoutSec; 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 @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (this == o) { if (this == o) {

@ -25,6 +25,7 @@ import org.hyperledger.besu.metrics.BesuMetricCategory;
import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Locale;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -34,6 +35,7 @@ import io.vertx.core.AsyncResult;
import io.vertx.core.Handler; import io.vertx.core.Handler;
import io.vertx.core.Vertx; import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer; import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.ClientAuth;
import io.vertx.core.http.HttpConnection; import io.vertx.core.http.HttpConnection;
import io.vertx.core.http.HttpServer; import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions; 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.HttpServerResponse;
import io.vertx.core.http.ServerWebSocket; import io.vertx.core.http.ServerWebSocket;
import io.vertx.core.net.HostAndPort; 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.core.net.SocketAddress;
import io.vertx.ext.web.Router; import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.RoutingContext;
@ -103,18 +108,65 @@ public class WebSocketService {
"Starting Websocket service on {}:{}", configuration.getHost(), configuration.getPort()); "Starting Websocket service on {}:{}", configuration.getHost(), configuration.getPort());
final CompletableFuture<?> resultFuture = new CompletableFuture<>(); final CompletableFuture<?> resultFuture = new CompletableFuture<>();
HttpServerOptions serverOptions =
new HttpServerOptions()
.setHost(configuration.getHost())
.setPort(configuration.getPort())
.setHandle100ContinueAutomatically(true)
.setCompressionSupported(true)
.addWebSocketSubProtocol("undefined")
.setMaxWebSocketFrameSize(configuration.getMaxFrameSize())
.setMaxWebSocketMessageSize(configuration.getMaxFrameSize() * 4)
.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 = httpServer =
vertx vertx
.createHttpServer( .createHttpServer(serverOptions)
new HttpServerOptions()
.setHost(configuration.getHost())
.setPort(configuration.getPort())
.setHandle100ContinueAutomatically(true)
.setCompressionSupported(true)
.addWebSocketSubProtocol("undefined")
.setMaxWebSocketFrameSize(configuration.getMaxFrameSize())
.setMaxWebSocketMessageSize(configuration.getMaxFrameSize() * 4)
.setRegisterWebSocketWriteHandlers(true))
.webSocketHandler(websocketHandler()) .webSocketHandler(websocketHandler())
.connectionHandler(connectionHandler()) .connectionHandler(connectionHandler())
.requestHandler(httpHandler()) .requestHandler(httpHandler())

@ -0,0 +1,198 @@
/*
* 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.internal.methods;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import org.hyperledger.besu.crypto.Hash;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpServiceTest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
import java.util.Optional;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
/**
* This test only exercises bonsai worldstate since forest is essentially a no-op for moving the
* worldstate.
*/
public class DebugSetHeadTest extends AbstractJsonRpcHttpServiceTest {
DebugSetHead debugSetHead;
Blockchain blockchain;
WorldStateArchive archive;
ProtocolContext protocolContext;
ProtocolSchedule protocolSchedule;
@Override
@BeforeEach
public void setup() throws Exception {
setupBonsaiBlockchain();
blockchain = blockchainSetupUtil.getBlockchain();
protocolContext = blockchainSetupUtil.getProtocolContext();
protocolSchedule = blockchainSetupUtil.getProtocolSchedule();
;
archive = blockchainSetupUtil.getWorldArchive();
debugSetHead =
new DebugSetHead(
new BlockchainQueries(
protocolSchedule, blockchain, archive, MiningConfiguration.MINING_DISABLED),
protocolContext,
// a value of 2 here exercises all the state rolling code paths
2);
startService();
}
@ParameterizedTest
@ValueSource(
strings = {"0x01", "0x4e9a67b663f9abe03e7e9fd5452c9497998337077122f44ee78a466f6a7358de"})
public void assertOnlyChainHeadMovesWorldParameterAbsent(final String blockParam) {
var chainTip = blockchain.getChainHead().getBlockHeader();
var blockOne = getBlockHeaderForHashOrNumber(blockParam).orElse(null);
assertThat(blockOne).isNotNull();
assertThat(blockOne).isNotEqualTo(chainTip);
// move the head to param val, number or hash
debugSetHead.response(debugSetHead(blockParam, Optional.empty()));
// get the new chainTip:
var newChainTip = blockchain.getChainHead().getBlockHeader();
// assert the chain moved, and the worldstate did not
assertThat(newChainTip).isEqualTo(blockOne);
assertThat(archive.getMutable().rootHash()).isEqualTo(chainTip.getStateRoot());
}
@ParameterizedTest
@ValueSource(
strings = {
"0x01",
"0x02",
"0x3d813a0ffc9cd04436e17e3e9c309f1e80df0407078e50355ce0d570b5424812",
"0x4e9a67b663f9abe03e7e9fd5452c9497998337077122f44ee78a466f6a7358de"
})
public void assertOnlyChainHeadMoves(final String blockParam) {
var chainTip = blockchain.getChainHead().getBlockHeader();
var blockOne = getBlockHeaderForHashOrNumber(blockParam).orElse(null);
assertThat(blockOne).isNotNull();
assertThat(blockOne).isNotEqualTo(chainTip);
// move the head to param val, number or hash
debugSetHead.response(debugSetHead(blockParam, Optional.of(FALSE)));
// get the new chainTip:
var newChainTip = blockchain.getChainHead().getBlockHeader();
// assert the chain moved, and the worldstate did not
assertThat(newChainTip).isEqualTo(blockOne);
assertThat(archive.getMutable().rootHash()).isEqualTo(chainTip.getStateRoot());
}
@ParameterizedTest
@ValueSource(
strings = {
"0x01",
"0x02",
"0x3d813a0ffc9cd04436e17e3e9c309f1e80df0407078e50355ce0d570b5424812",
"0x4e9a67b663f9abe03e7e9fd5452c9497998337077122f44ee78a466f6a7358de"
})
public void assertBothChainHeadAndWorldStatByNumber(final String blockParam) {
var chainTip = blockchain.getChainHead().getBlockHeader();
var blockOne = getBlockHeaderForHashOrNumber(blockParam).orElse(null);
assertThat(blockOne).isNotNull();
assertThat(blockOne).isNotEqualTo(chainTip);
// move the head and worldstate to param val number or hash
debugSetHead.response(debugSetHead(blockParam, Optional.of(TRUE)));
// get the new chainTip:
var newChainTip = blockchain.getChainHead().getBlockHeader();
// assert both the chain and worldstate moved to block one
assertThat(newChainTip).isEqualTo(blockOne);
assertThat(archive.getMutable().rootHash()).isEqualTo(blockOne.getStateRoot());
}
@Test
public void assertNotFound() {
var chainTip = blockchain.getChainHead().getBlockHeader();
// move the head to number just after chain head
var resp =
debugSetHead.response(debugSetHead("" + chainTip.getNumber() + 1, Optional.of(TRUE)));
assertThat(resp.getType()).isEqualTo(RpcResponseType.ERROR);
// move the head to some arbitrary hash
var resp2 =
debugSetHead.response(
debugSetHead(
Hash.keccak256(Bytes.fromHexString("0xdeadbeef")).toHexString(),
Optional.of(TRUE)));
assertThat(resp2.getType()).isEqualTo(RpcResponseType.ERROR);
// get the new chainTip:
var newChainTip = blockchain.getChainHead().getBlockHeader();
// assert neither the chain nor the worldstate moved
assertThat(newChainTip).isEqualTo(chainTip);
assertThat(archive.getMutable().rootHash()).isEqualTo(chainTip.getStateRoot());
}
private JsonRpcRequestContext debugSetHead(
final String numberOrHash, final Optional<Boolean> moveWorldState) {
if (moveWorldState.isPresent()) {
return new JsonRpcRequestContext(
new JsonRpcRequest(
"2.0", "debug_setHead", new Object[] {numberOrHash, moveWorldState.get()}));
} else {
return new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "debug_setHead", new Object[] {numberOrHash}));
}
}
private Optional<BlockHeader> getBlockHeaderForHashOrNumber(final String input) {
try {
var param = new BlockParameterOrBlockHash(input);
if (param.getHash().isPresent()) {
return blockchain.getBlockHeader(param.getHash().get());
} else if (param.getNumber().isPresent()) {
return blockchain.getBlockHeader(param.getNumber().getAsLong());
}
} catch (JsonProcessingException ignored) {
// meh
}
return Optional.empty();
}
}

@ -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))); Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests)));
} }
} catch (MerkleTrieException ex) { } catch (MerkleTrieException ex) {
context.getSynchronizer().healWorldState(ex.getMaybeAddress(), ex.getLocation()); context.getWorldStateArchive().heal(ex.getMaybeAddress(), ex.getLocation());
return new BlockProcessingResult(Optional.empty(), ex); return new BlockProcessingResult(Optional.empty(), ex);
} catch (StorageException ex) { } catch (StorageException ex) {
var retval = new BlockProcessingResult(Optional.empty(), 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.BadBlockManager;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain; 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.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
@ -32,7 +31,6 @@ public class ProtocolContext {
private final WorldStateArchive worldStateArchive; private final WorldStateArchive worldStateArchive;
private final BadBlockManager badBlockManager; private final BadBlockManager badBlockManager;
private final ConsensusContext consensusContext; private final ConsensusContext consensusContext;
private Synchronizer synchronizer;
/** /**
* Constructs a new ProtocolContext with the given blockchain, world state archive, consensus * Constructs a new ProtocolContext with the given blockchain, world state archive, consensus
@ -78,24 +76,6 @@ public class ProtocolContext {
badBlockManager); 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. * Gets the blockchain of the protocol context.
* *

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

@ -64,4 +64,24 @@ public interface WorldStateArchive extends Closeable {
final Address accountAddress, final Address accountAddress,
final List<UInt256> accountStorageKeys, final List<UInt256> accountStorageKeys,
final Function<Optional<WorldStateProof>, ? extends Optional<U>> mapper); 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()); genesisState.writeStateTo(worldArchive.getMutable());
final ProtocolContext protocolContext = protocolContextProvider.get(blockchain, worldArchive); final ProtocolContext protocolContext = protocolContextProvider.get(blockchain, worldArchive);
protocolContext.setSynchronizer(new DummySynchronizer());
final Path blocksPath = Path.of(chainResources.getBlocksURL().toURI()); final Path blocksPath = Path.of(chainResources.getBlocksURL().toURI());
final List<Block> blocks = new ArrayList<>(); final List<Block> blocks = new ArrayList<>();

@ -14,6 +14,8 @@
*/ */
package org.hyperledger.besu.ethereum.core; 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.Blockchain;
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain; import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
@ -105,7 +107,8 @@ public class InMemoryKeyValueStorageProvider extends KeyValueStorageProvider {
Optional.empty(), Optional.empty(),
bonsaiCachedMerkleTrieLoader, bonsaiCachedMerkleTrieLoader,
null, null,
evmConfiguration); evmConfiguration,
throwingWorldStateHealerSupplier());
} }
public static MutableWorldState createInMemoryWorldState() { 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.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
import org.hyperledger.besu.ethereum.core.MutableWorldState; 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.BlockBodyValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; import org.hyperledger.besu.ethereum.mainnet.BlockProcessor;
@ -91,7 +90,6 @@ public class MainnetBlockValidatorTest {
when(protocolContext.getBlockchain()).thenReturn(blockchain); when(protocolContext.getBlockchain()).thenReturn(blockchain);
when(protocolContext.getWorldStateArchive()).thenReturn(worldStateArchive); when(protocolContext.getWorldStateArchive()).thenReturn(worldStateArchive);
when(protocolContext.getSynchronizer()).thenReturn(mock(Synchronizer.class));
when(worldStateArchive.getMutable(any(BlockHeader.class), anyBoolean())) when(worldStateArchive.getMutable(any(BlockHeader.class), anyBoolean()))
.thenReturn(Optional.of(worldState)); .thenReturn(Optional.of(worldState));
when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class))) when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class)))

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

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

@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.eth.manager.snap; package org.hyperledger.besu.ethereum.eth.manager.snap;
import org.hyperledger.besu.ethereum.ProtocolContext; 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.SnapProtocol;
import org.hyperledger.besu.ethereum.eth.manager.EthMessage; import org.hyperledger.besu.ethereum.eth.manager.EthMessage;
import org.hyperledger.besu.ethereum.eth.manager.EthMessages; import org.hyperledger.besu.ethereum.eth.manager.EthMessages;
@ -53,11 +54,13 @@ public class SnapProtocolManager implements ProtocolManager {
final SnapSyncConfiguration snapConfig, final SnapSyncConfiguration snapConfig,
final EthPeers ethPeers, final EthPeers ethPeers,
final EthMessages snapMessages, final EthMessages snapMessages,
final ProtocolContext protocolContext) { final ProtocolContext protocolContext,
final Synchronizer synchronizer) {
this.ethPeers = ethPeers; this.ethPeers = ethPeers;
this.snapMessages = snapMessages; this.snapMessages = snapMessages;
this.supportedCapabilities = calculateCapabilities(); this.supportedCapabilities = calculateCapabilities();
new SnapServer(snapConfig, snapMessages, worldStateStorageCoordinator, protocolContext); new SnapServer(
snapConfig, snapMessages, worldStateStorageCoordinator, protocolContext, synchronizer);
} }
private List<Capability> calculateCapabilities() { 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.datatypes.Hash;
import org.hyperledger.besu.ethereum.ProtocolContext; 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.manager.EthMessages;
import org.hyperledger.besu.ethereum.eth.messages.snap.AccountRangeMessage; import org.hyperledger.besu.ethereum.eth.messages.snap.AccountRangeMessage;
import org.hyperledger.besu.ethereum.eth.messages.snap.ByteCodesMessage; import org.hyperledger.besu.ethereum.eth.messages.snap.ByteCodesMessage;
@ -98,7 +99,8 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener {
final SnapSyncConfiguration snapConfig, final SnapSyncConfiguration snapConfig,
final EthMessages snapMessages, final EthMessages snapMessages,
final WorldStateStorageCoordinator worldStateStorageCoordinator, final WorldStateStorageCoordinator worldStateStorageCoordinator,
final ProtocolContext protocolContext) { final ProtocolContext protocolContext,
final Synchronizer synchronizer) {
this.snapServerEnabled = this.snapServerEnabled =
Optional.ofNullable(snapConfig) Optional.ofNullable(snapConfig)
.map(SnapSyncConfiguration::isSnapServerEnabled) .map(SnapSyncConfiguration::isSnapServerEnabled)
@ -110,7 +112,7 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener {
// subscribe to initial sync completed events to start/stop snap server, // subscribe to initial sync completed events to start/stop snap server,
// not saving the listenerId since we never need to unsubscribe. // 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.Logger;
import org.slf4j.LoggerFactory; 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 Logger LOG = LoggerFactory.getLogger(TransactionBroadcaster.class);
private static final EnumSet<TransactionType> ANNOUNCE_HASH_ONLY_TX_TYPES = EnumSet.of(BLOB); 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)); 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); subscribePendingTransactions(this::mapBlobsOnTransactionAdded);
subscribeDroppedTransactions( subscribeDroppedTransactions(
(transaction, reason) -> unmapBlobsOnTransactionDropped(transaction)); (transaction, reason) -> unmapBlobsOnTransactionDropped(transaction));
subscribeDroppedTransactions(transactionBroadcaster);
} }
private void initLogForReplay() { private void initLogForReplay() {

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

@ -68,13 +68,21 @@ public class PushOperation extends AbstractFixedCostOperation {
*/ */
public static OperationResult staticOperation( public static OperationResult staticOperation(
final MessageFrame frame, final byte[] code, final int pc, final int pushSize) { final MessageFrame frame, final byte[] code, final int pc, final int pushSize) {
int copyStart = pc + 1; final int copyStart = pc + 1;
Bytes push; Bytes push;
if (code.length <= copyStart) { if (code.length <= copyStart) {
push = Bytes.EMPTY; push = Bytes.EMPTY;
} else { } else {
final int copyLength = Math.min(pushSize, code.length - pc - 1); final int copyLength = Math.min(pushSize, code.length - pc - 1);
push = Bytes.wrap(code, copyStart, copyLength); final int rightPad = pushSize - copyLength;
if (rightPad == 0) {
push = Bytes.wrap(code, copyStart, copyLength);
} else {
// Right Pad the push with 0s up to pushSize if greater than the copyLength
var bytecodeLocal = new byte[pushSize];
System.arraycopy(code, copyStart, bytecodeLocal, 0, copyLength);
push = Bytes.wrap(bytecodeLocal);
}
} }
frame.pushStackItem(push); frame.pushStackItem(push);
frame.setPC(pc + pushSize); frame.setPC(pc + pushSize);

@ -0,0 +1,83 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evm.operation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.evm.operation.PushOperation.staticOperation;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.code.CodeV0;
import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.toy.ToyBlockValues;
import org.hyperledger.besu.evm.toy.ToyWorld;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class PushOperationTest {
private static final byte[] byteCode = new byte[] {0x00, 0x01, 0x02, 0x03};
private static final MessageFrame frame =
MessageFrame.builder()
.worldUpdater(new ToyWorld())
.originator(Address.ZERO)
.gasPrice(Wei.ONE)
.blobGasPrice(Wei.ONE)
.blockValues(new ToyBlockValues())
.miningBeneficiary(Address.ZERO)
.blockHashLookup((l) -> Hash.ZERO)
.type(MessageFrame.Type.MESSAGE_CALL)
.initialGas(1)
.address(Address.ZERO)
.contract(Address.ZERO)
.inputData(Bytes32.ZERO)
.sender(Address.ZERO)
.value(Wei.ZERO)
.apparentValue(Wei.ZERO)
.code(CodeV0.EMPTY_CODE)
.completer(messageFrame -> {})
.build();
;
@Test
void unpaddedPushDoesntReachEndCode() {
staticOperation(frame, byteCode, 0, byteCode.length - 2);
assertThat(frame.getStackItem(0).equals(Bytes.fromHexString("0x0102"))).isTrue();
}
@Test
void unpaddedPushUpReachesEndCode() {
staticOperation(frame, byteCode, 0, byteCode.length - 1);
assertThat(frame.getStackItem(0).equals(Bytes.fromHexString("0x010203"))).isTrue();
}
@Test
void paddedPush() {
staticOperation(frame, byteCode, 1, byteCode.length - 1);
assertThat(frame.getStackItem(0).equals(Bytes.fromHexString("0x020300"))).isTrue();
}
@Test
void oobPush() {
staticOperation(frame, byteCode, byteCode.length, byteCode.length - 1);
assertThat(frame.getStackItem(0).equals(Bytes.EMPTY)).isTrue();
}
}

@ -1932,6 +1932,14 @@
<sha256 value="cf743ff8a0143fe3fc6a803f0b225014c23b5a2ea25632bf704c07845386d3af" origin="Generated by Gradle"/> <sha256 value="cf743ff8a0143fe3fc6a803f0b225014c23b5a2ea25632bf704c07845386d3af" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-bom" version="4.1.111.Final">
<artifact name="netty-bom-4.1.111.Final.pom"> <artifact name="netty-bom-4.1.111.Final.pom">
<sha256 value="2f113902364208bbb32d551e062b05ab219692fbc12bd48de1d83c7576e5b470" origin="Generated by Gradle"/> <sha256 value="2f113902364208bbb32d551e062b05ab219692fbc12bd48de1d83c7576e5b470" origin="Generated by Gradle"/>
@ -1942,6 +1950,11 @@
<sha256 value="0dfd08abc106f625be1d6eb498fa993de65c8b558070dfb11afa9a3394bb6612" origin="Generated by Gradle"/> <sha256 value="0dfd08abc106f625be1d6eb498fa993de65c8b558070dfb11afa9a3394bb6612" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-buffer" version="4.1.111.Final">
<artifact name="netty-buffer-4.1.111.Final.pom"> <artifact name="netty-buffer-4.1.111.Final.pom">
<sha256 value="6afc7e751e0a90d2cb1168f6a4854d80bf3ba888104afab303233cd31684f4b4" origin="Generated by Gradle"/> <sha256 value="6afc7e751e0a90d2cb1168f6a4854d80bf3ba888104afab303233cd31684f4b4" origin="Generated by Gradle"/>
@ -1955,6 +1968,14 @@
<sha256 value="b3f07cf4271ee5a4a459ea8a0d9f4f16911a9355357831d05710ef64f8b8c5ce" origin="Generated by Gradle"/> <sha256 value="b3f07cf4271ee5a4a459ea8a0d9f4f16911a9355357831d05710ef64f8b8c5ce" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec" version="4.1.114.Final">
<artifact name="netty-codec-4.1.114.Final.jar"> <artifact name="netty-codec-4.1.114.Final.jar">
<sha256 value="71d145491456b53212e38e24787bbbed0c77d850f7352e24e535d26a6eea913b" origin="Generated by Gradle"/> <sha256 value="71d145491456b53212e38e24787bbbed0c77d850f7352e24e535d26a6eea913b" origin="Generated by Gradle"/>
@ -1963,6 +1984,14 @@
<sha256 value="f55160abec463634c36459914cc60cb59489dcb723e87e9a71ac37bdf3706b84" origin="Generated by Gradle"/> <sha256 value="f55160abec463634c36459914cc60cb59489dcb723e87e9a71ac37bdf3706b84" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-dns" version="4.1.114.Final">
<artifact name="netty-codec-dns-4.1.114.Final.jar"> <artifact name="netty-codec-dns-4.1.114.Final.jar">
<sha256 value="7b97b856d062e7b2483384223dcee002ad23d526f827991f1140af6302ca120d" origin="Generated by Gradle"/> <sha256 value="7b97b856d062e7b2483384223dcee002ad23d526f827991f1140af6302ca120d" origin="Generated by Gradle"/>
@ -1971,6 +2000,14 @@
<sha256 value="24577daa4d8ab270fd6dc51d1ecca5be383e3df14450d35ae83e048d9981aa32" origin="Generated by Gradle"/> <sha256 value="24577daa4d8ab270fd6dc51d1ecca5be383e3df14450d35ae83e048d9981aa32" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-haproxy" version="4.1.114.Final">
<artifact name="netty-codec-haproxy-4.1.114.Final.jar"> <artifact name="netty-codec-haproxy-4.1.114.Final.jar">
<sha256 value="a96216d347c7219f69b2f4f8743ce0aee6ac750b3691739745ebbcc10eb49528" origin="Generated by Gradle"/> <sha256 value="a96216d347c7219f69b2f4f8743ce0aee6ac750b3691739745ebbcc10eb49528" origin="Generated by Gradle"/>
@ -1979,6 +2016,14 @@
<sha256 value="a399be4607a97549d249ad76f2fcf6e092af63d344e3272efd44df21757ccfe0" origin="Generated by Gradle"/> <sha256 value="a399be4607a97549d249ad76f2fcf6e092af63d344e3272efd44df21757ccfe0" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-http" version="4.1.111.Final">
<artifact name="netty-codec-http-4.1.111.Final.pom"> <artifact name="netty-codec-http-4.1.111.Final.pom">
<sha256 value="80372e3e6e61ba8b3abe623964c986376568b6bbec705adb29d2a959cd7b9f8c" origin="Generated by Gradle"/> <sha256 value="80372e3e6e61ba8b3abe623964c986376568b6bbec705adb29d2a959cd7b9f8c" origin="Generated by Gradle"/>
@ -1992,6 +2037,14 @@
<sha256 value="e8fe9ebb862f1dd5c3a6be87e851a3b3b28a7eec4af8d70acbecb0c1e816f3ae" origin="Generated by Gradle"/> <sha256 value="e8fe9ebb862f1dd5c3a6be87e851a3b3b28a7eec4af8d70acbecb0c1e816f3ae" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-http2" version="4.1.111.Final">
<artifact name="netty-codec-http2-4.1.111.Final.pom"> <artifact name="netty-codec-http2-4.1.111.Final.pom">
<sha256 value="c7f0325aa4c75c9eae1e388306dc7d10426c6a2a6c8f712f876f58a4bc157ede" origin="Generated by Gradle"/> <sha256 value="c7f0325aa4c75c9eae1e388306dc7d10426c6a2a6c8f712f876f58a4bc157ede" origin="Generated by Gradle"/>
@ -2005,6 +2058,14 @@
<sha256 value="a856ee4a1cc7d497b664b9125b3c90a690091ff771beca2a9858d51858a75850" origin="Generated by Gradle"/> <sha256 value="a856ee4a1cc7d497b664b9125b3c90a690091ff771beca2a9858d51858a75850" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-memcache" version="4.1.114.Final">
<artifact name="netty-codec-memcache-4.1.114.Final.jar"> <artifact name="netty-codec-memcache-4.1.114.Final.jar">
<sha256 value="7ef9cfa35408cf43196ad41b7d31517d4a29fbc3c52f387f7c1930ebc02e3c3b" origin="Generated by Gradle"/> <sha256 value="7ef9cfa35408cf43196ad41b7d31517d4a29fbc3c52f387f7c1930ebc02e3c3b" origin="Generated by Gradle"/>
@ -2013,6 +2074,14 @@
<sha256 value="9748096cc41e8de6c78d4cea259ea222a7af70756f783b612b83c9f36e62e848" origin="Generated by Gradle"/> <sha256 value="9748096cc41e8de6c78d4cea259ea222a7af70756f783b612b83c9f36e62e848" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-mqtt" version="4.1.114.Final">
<artifact name="netty-codec-mqtt-4.1.114.Final.jar"> <artifact name="netty-codec-mqtt-4.1.114.Final.jar">
<sha256 value="4e5d5e05a26399f8431beb61fb4860b554938bbfba9d633cfb8c69444a089cc8" origin="Generated by Gradle"/> <sha256 value="4e5d5e05a26399f8431beb61fb4860b554938bbfba9d633cfb8c69444a089cc8" origin="Generated by Gradle"/>
@ -2021,6 +2090,14 @@
<sha256 value="e31ab2e3030a3a3b10ab85abe6547f9c214de55d5b69251dee76367c6bf6ab98" origin="Generated by Gradle"/> <sha256 value="e31ab2e3030a3a3b10ab85abe6547f9c214de55d5b69251dee76367c6bf6ab98" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-redis" version="4.1.114.Final">
<artifact name="netty-codec-redis-4.1.114.Final.jar"> <artifact name="netty-codec-redis-4.1.114.Final.jar">
<sha256 value="8b31e03a59c4d460f9f6306a6b8ef1ee856f93a24ed94f8e47fc2cd0d77ffd0d" origin="Generated by Gradle"/> <sha256 value="8b31e03a59c4d460f9f6306a6b8ef1ee856f93a24ed94f8e47fc2cd0d77ffd0d" origin="Generated by Gradle"/>
@ -2029,6 +2106,14 @@
<sha256 value="520a82274a95583df659bb7b2a70ad8864396f02e6fefcd989f688f18f5748c9" origin="Generated by Gradle"/> <sha256 value="520a82274a95583df659bb7b2a70ad8864396f02e6fefcd989f688f18f5748c9" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-smtp" version="4.1.114.Final">
<artifact name="netty-codec-smtp-4.1.114.Final.jar"> <artifact name="netty-codec-smtp-4.1.114.Final.jar">
<sha256 value="78285748b6e50b2275e32579353638424afdc117e3919c9a01fd8deb4974a6d8" origin="Generated by Gradle"/> <sha256 value="78285748b6e50b2275e32579353638424afdc117e3919c9a01fd8deb4974a6d8" origin="Generated by Gradle"/>
@ -2037,6 +2122,14 @@
<sha256 value="20219aaaaf7a534b5f0d142ca39f83234273069eb6f59779818e94f4c3630b1c" origin="Generated by Gradle"/> <sha256 value="20219aaaaf7a534b5f0d142ca39f83234273069eb6f59779818e94f4c3630b1c" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-socks" version="4.1.114.Final">
<artifact name="netty-codec-socks-4.1.114.Final.jar"> <artifact name="netty-codec-socks-4.1.114.Final.jar">
<sha256 value="2e48cb5af7cae82acbb8dcb7b0c9d67b9dddff3d6dd262cb8911fd4b5fd62ee2" origin="Generated by Gradle"/> <sha256 value="2e48cb5af7cae82acbb8dcb7b0c9d67b9dddff3d6dd262cb8911fd4b5fd62ee2" origin="Generated by Gradle"/>
@ -2045,6 +2138,14 @@
<sha256 value="374f2d39e95f0106a22d4e4c42c5ed6f377027a61c6e8f1bf72b0fb12823da06" origin="Generated by Gradle"/> <sha256 value="374f2d39e95f0106a22d4e4c42c5ed6f377027a61c6e8f1bf72b0fb12823da06" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-stomp" version="4.1.114.Final">
<artifact name="netty-codec-stomp-4.1.114.Final.jar"> <artifact name="netty-codec-stomp-4.1.114.Final.jar">
<sha256 value="9b63156b727843485b137c87e2c7e4c7db2690f5ca93443080711a1804d685cf" origin="Generated by Gradle"/> <sha256 value="9b63156b727843485b137c87e2c7e4c7db2690f5ca93443080711a1804d685cf" origin="Generated by Gradle"/>
@ -2053,6 +2154,14 @@
<sha256 value="d4e8f0900d3dd2e6d9f74bbae8b4b427c21c8b18f388a41b0205ae7f0335ac20" origin="Generated by Gradle"/> <sha256 value="d4e8f0900d3dd2e6d9f74bbae8b4b427c21c8b18f388a41b0205ae7f0335ac20" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-codec-xml" version="4.1.114.Final">
<artifact name="netty-codec-xml-4.1.114.Final.jar"> <artifact name="netty-codec-xml-4.1.114.Final.jar">
<sha256 value="3a2055a9b38b603ea9fcbfbe891172daad60df99aecd99161f1c8adbedc95522" origin="Generated by Gradle"/> <sha256 value="3a2055a9b38b603ea9fcbfbe891172daad60df99aecd99161f1c8adbedc95522" origin="Generated by Gradle"/>
@ -2061,6 +2170,14 @@
<sha256 value="e5fcbcb730801bf08dc5b8575b2545766a61331e0e285d05fd805602564deb5f" origin="Generated by Gradle"/> <sha256 value="e5fcbcb730801bf08dc5b8575b2545766a61331e0e285d05fd805602564deb5f" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-common" version="4.1.111.Final">
<artifact name="netty-common-4.1.111.Final.pom"> <artifact name="netty-common-4.1.111.Final.pom">
<sha256 value="b9c78337616bf8d54d5515bab6cba1df2db46fdb01b412434cc7fbafe78345c5" origin="Generated by Gradle"/> <sha256 value="b9c78337616bf8d54d5515bab6cba1df2db46fdb01b412434cc7fbafe78345c5" origin="Generated by Gradle"/>
@ -2074,6 +2191,14 @@
<sha256 value="3c2e7d18133ac6d8e4f442cc5fa5fe0492f5cbf878bf0f7157c6d410da719f5d" origin="Generated by Gradle"/> <sha256 value="3c2e7d18133ac6d8e4f442cc5fa5fe0492f5cbf878bf0f7157c6d410da719f5d" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-handler" version="4.1.111.Final">
<artifact name="netty-handler-4.1.111.Final.pom"> <artifact name="netty-handler-4.1.111.Final.pom">
<sha256 value="f575d446fa5cd546be4fce0bbf34c144041761b89da77971e30bf83d42905d1b" origin="Generated by Gradle"/> <sha256 value="f575d446fa5cd546be4fce0bbf34c144041761b89da77971e30bf83d42905d1b" origin="Generated by Gradle"/>
@ -2087,6 +2212,14 @@
<sha256 value="694fe6fb8dfe9148a2326e77f56141fcebbccc2cb8b29f285776796164ec6a93" origin="Generated by Gradle"/> <sha256 value="694fe6fb8dfe9148a2326e77f56141fcebbccc2cb8b29f285776796164ec6a93" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-handler-proxy" version="4.1.111.Final">
<artifact name="netty-handler-proxy-4.1.111.Final.pom"> <artifact name="netty-handler-proxy-4.1.111.Final.pom">
<sha256 value="8577aa45f16f435b12420a37b8c8d731df11d4dcb7e132c00fc588946274ed89" origin="Generated by Gradle"/> <sha256 value="8577aa45f16f435b12420a37b8c8d731df11d4dcb7e132c00fc588946274ed89" origin="Generated by Gradle"/>
@ -2100,6 +2233,14 @@
<sha256 value="6cdaeb2a8f240fa1b72382476e2776969535678203d9902f3e63ef586ac0dbb7" origin="Generated by Gradle"/> <sha256 value="6cdaeb2a8f240fa1b72382476e2776969535678203d9902f3e63ef586ac0dbb7" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <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"> <artifact name="netty-handler-ssl-ocsp-4.1.114.Final.jar">
<sha256 value="c97e307e99bb9555adae0f01ddcd690965408aa1b653122fc7a02030dd73d8f7" origin="Generated by Gradle"/> <sha256 value="c97e307e99bb9555adae0f01ddcd690965408aa1b653122fc7a02030dd73d8f7" origin="Generated by Gradle"/>
@ -2108,6 +2249,14 @@
<sha256 value="d217e882bd1fa6fbc6bfa3966b68fcade287ec6806c26ab9b0d80d4fc9daa694" origin="Generated by Gradle"/> <sha256 value="d217e882bd1fa6fbc6bfa3966b68fcade287ec6806c26ab9b0d80d4fc9daa694" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-parent" version="4.1.111.Final">
<artifact name="netty-parent-4.1.111.Final.pom"> <artifact name="netty-parent-4.1.111.Final.pom">
<sha256 value="96b055ae7af7f1e32db3d7261918d900fba15e1e589ccd682f9cfd5744249a51" origin="Generated by Gradle"/> <sha256 value="96b055ae7af7f1e32db3d7261918d900fba15e1e589ccd682f9cfd5744249a51" origin="Generated by Gradle"/>
@ -2118,6 +2267,11 @@
<sha256 value="a1c8a553ae7e43bf0ed986d22f0379dcf0c2fb7fc3971dc6057ed5c9d04c5a68" origin="Generated by Gradle"/> <sha256 value="a1c8a553ae7e43bf0ed986d22f0379dcf0c2fb7fc3971dc6057ed5c9d04c5a68" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-resolver" version="4.1.111.Final">
<artifact name="netty-resolver-4.1.111.Final.pom"> <artifact name="netty-resolver-4.1.111.Final.pom">
<sha256 value="d7524053459d425c9cbbbf93f0793504c4d0148c75fb49daab3e14d4e4d38ef0" origin="Generated by Gradle"/> <sha256 value="d7524053459d425c9cbbbf93f0793504c4d0148c75fb49daab3e14d4e4d38ef0" origin="Generated by Gradle"/>
@ -2131,6 +2285,14 @@
<sha256 value="86843905401f6605d575f4858b58c1eadcf1e3c0bccd417787cb0ad0621cc120" origin="Generated by Gradle"/> <sha256 value="86843905401f6605d575f4858b58c1eadcf1e3c0bccd417787cb0ad0621cc120" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-resolver-dns" version="4.1.111.Final">
<artifact name="netty-resolver-dns-4.1.111.Final.pom"> <artifact name="netty-resolver-dns-4.1.111.Final.pom">
<sha256 value="9d4607157d264015d8e8ae825d49fb8d8bf48fe227de99d82fb5570ac519c70a" origin="Generated by Gradle"/> <sha256 value="9d4607157d264015d8e8ae825d49fb8d8bf48fe227de99d82fb5570ac519c70a" origin="Generated by Gradle"/>
@ -2144,6 +2306,14 @@
<sha256 value="ed126dff491fe7175d0069141ca53ecb594c486c290c2ee13e99d25d72456fb4" origin="Generated by Gradle"/> <sha256 value="ed126dff491fe7175d0069141ca53ecb594c486c290c2ee13e99d25d72456fb4" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <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"> <artifact name="netty-resolver-dns-classes-macos-4.1.114.Final.jar">
<sha256 value="2bc4078cf269a99e09f28738d6022c385a31f4321e28115bae752ce16ce99618" origin="Generated by Gradle"/> <sha256 value="2bc4078cf269a99e09f28738d6022c385a31f4321e28115bae752ce16ce99618" origin="Generated by Gradle"/>
@ -2152,6 +2322,14 @@
<sha256 value="e530a68c73ea6f1c0a78c616ff29ce0a7a7a22f86ebcef27fa02965e6acbd660" origin="Generated by Gradle"/> <sha256 value="e530a68c73ea6f1c0a78c616ff29ce0a7a7a22f86ebcef27fa02965e6acbd660" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <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"> <artifact name="netty-resolver-dns-native-macos-4.1.114.Final-osx-aarch_64.jar">
<sha256 value="c63ffafc1becb7e1dca29c89b1c69ea74cc62abe3fcc3184ea7f089c76bac643" origin="Generated by Gradle"/> <sha256 value="c63ffafc1becb7e1dca29c89b1c69ea74cc62abe3fcc3184ea7f089c76bac643" origin="Generated by Gradle"/>
@ -2163,6 +2341,17 @@
<sha256 value="710dbb92f3edbe204aea06dada1671f2382cd369f0ea47e6d5e03d0aa684929c" origin="Generated by Gradle"/> <sha256 value="710dbb92f3edbe204aea06dada1671f2382cd369f0ea47e6d5e03d0aa684929c" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <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"> <artifact name="netty-tcnative-boringssl-static-2.0.65.Final.pom">
<sha256 value="ba89f115a8c30bdbcb6dba36849a047da803b496f3e856e4365d53df1403932d" origin="Generated by Gradle"/> <sha256 value="ba89f115a8c30bdbcb6dba36849a047da803b496f3e856e4365d53df1403932d" origin="Generated by Gradle"/>
@ -2176,6 +2365,14 @@
<sha256 value="7ea6c8ee65df3595dfc044ed2e95614acecab6da0b348b7a1e9361cba44fce2f" origin="Generated by Gradle"/> <sha256 value="7ea6c8ee65df3595dfc044ed2e95614acecab6da0b348b7a1e9361cba44fce2f" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-tcnative-classes" version="2.0.66.Final">
<artifact name="netty-tcnative-classes-2.0.66.Final.jar"> <artifact name="netty-tcnative-classes-2.0.66.Final.jar">
<sha256 value="669a811a193dc1e7c9ef86cb547a4ab92f0f34cce8f9b842b9029bf5cfa07cc5" origin="Generated by Gradle"/> <sha256 value="669a811a193dc1e7c9ef86cb547a4ab92f0f34cce8f9b842b9029bf5cfa07cc5" origin="Generated by Gradle"/>
@ -2184,11 +2381,24 @@
<sha256 value="4942cd02e2916c1fb4f78cca8841f0f7219bb90f828ab7489a89027c2efa91eb" origin="Generated by Gradle"/> <sha256 value="4942cd02e2916c1fb4f78cca8841f0f7219bb90f828ab7489a89027c2efa91eb" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-tcnative-parent" version="2.0.66.Final">
<artifact name="netty-tcnative-parent-2.0.66.Final.pom"> <artifact name="netty-tcnative-parent-2.0.66.Final.pom">
<sha256 value="2b017fb3c1deeab5d1eaebec134659b7deae78c14d5ebfc3d49c0b3084ea7365" origin="Generated by Gradle"/> <sha256 value="2b017fb3c1deeab5d1eaebec134659b7deae78c14d5ebfc3d49c0b3084ea7365" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-transport" version="4.1.111.Final">
<artifact name="netty-transport-4.1.111.Final.pom"> <artifact name="netty-transport-4.1.111.Final.pom">
<sha256 value="8662bd5d7f62d372548f40ad896b87ea55c2b1d179029ef985837dce43a52269" origin="Generated by Gradle"/> <sha256 value="8662bd5d7f62d372548f40ad896b87ea55c2b1d179029ef985837dce43a52269" origin="Generated by Gradle"/>
@ -2202,6 +2412,14 @@
<sha256 value="9451b10917afd228c5892541d94acc3d6814c8d73589c4050c779a921fab9c82" origin="Generated by Gradle"/> <sha256 value="9451b10917afd228c5892541d94acc3d6814c8d73589c4050c779a921fab9c82" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <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"> <artifact name="netty-transport-classes-epoll-4.1.114.Final.jar">
<sha256 value="a90b4277df568be0562e08271060a28870c57ba5a91fe792057f11e986fe777e" origin="Generated by Gradle"/> <sha256 value="a90b4277df568be0562e08271060a28870c57ba5a91fe792057f11e986fe777e" origin="Generated by Gradle"/>
@ -2210,6 +2428,14 @@
<sha256 value="66c775019d67b3a40a6880265b90dc88b01660c53db7ae2f65cfea5e74994715" origin="Generated by Gradle"/> <sha256 value="66c775019d67b3a40a6880265b90dc88b01660c53db7ae2f65cfea5e74994715" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <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"> <artifact name="netty-transport-classes-kqueue-4.1.114.Final.jar">
<sha256 value="8a07fed5985502dd68936f70b0dd5639d2e69c257c2300610936ce0e6da9847d" origin="Generated by Gradle"/> <sha256 value="8a07fed5985502dd68936f70b0dd5639d2e69c257c2300610936ce0e6da9847d" origin="Generated by Gradle"/>
@ -2218,6 +2444,14 @@
<sha256 value="90cbf66fe7c2a185aaf2dc28b0136f8ef8ba8eb51be1c319bcbd7f7372af09f5" origin="Generated by Gradle"/> <sha256 value="90cbf66fe7c2a185aaf2dc28b0136f8ef8ba8eb51be1c319bcbd7f7372af09f5" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <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"> <artifact name="netty-transport-native-epoll-4.1.111.Final.pom">
<sha256 value="c14b3e677409871ae1cb80436dd06945591ae201ce3cc96db6a52957c7b9e574" origin="Generated by Gradle"/> <sha256 value="c14b3e677409871ae1cb80436dd06945591ae201ce3cc96db6a52957c7b9e574" origin="Generated by Gradle"/>
@ -2240,6 +2474,23 @@
<sha256 value="92d4dee865dc002fef64e19e602b6f6616667da22568869fb1135715a0344bf8" origin="Generated by Gradle"/> <sha256 value="92d4dee865dc002fef64e19e602b6f6616667da22568869fb1135715a0344bf8" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <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"> <artifact name="netty-transport-native-kqueue-4.1.111.Final.pom">
<sha256 value="d1bf448ced9703e41e63f539f8523246f2a163434ddf4330d213262e731d5707" origin="Generated by Gradle"/> <sha256 value="d1bf448ced9703e41e63f539f8523246f2a163434ddf4330d213262e731d5707" origin="Generated by Gradle"/>
@ -2259,6 +2510,20 @@
<sha256 value="0ca766af3bb08dfa44747c7cac67b408d5b6cc1fed051febc1b423edc077afb7" origin="Generated by Gradle"/> <sha256 value="0ca766af3bb08dfa44747c7cac67b408d5b6cc1fed051febc1b423edc077afb7" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <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"> <artifact name="netty-transport-native-unix-common-4.1.111.Final.pom">
<sha256 value="2ea70a1864ab38fcec2bdc28c69ee9756dbad58a4626c664554d3c860d540981" origin="Generated by Gradle"/> <sha256 value="2ea70a1864ab38fcec2bdc28c69ee9756dbad58a4626c664554d3c860d540981" origin="Generated by Gradle"/>
@ -2272,6 +2537,14 @@
<sha256 value="832b43c284e2c0cf0f57d62928fa72967b6aa6e5dc8766c6c9b2d01fddf7951d" origin="Generated by Gradle"/> <sha256 value="832b43c284e2c0cf0f57d62928fa72967b6aa6e5dc8766c6c9b2d01fddf7951d" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-transport-rxtx" version="4.1.114.Final">
<artifact name="netty-transport-rxtx-4.1.114.Final.jar"> <artifact name="netty-transport-rxtx-4.1.114.Final.jar">
<sha256 value="8927af869c006d73921d9db739d747f82fe5568c82ad8c1982fef954c5ecb63d" origin="Generated by Gradle"/> <sha256 value="8927af869c006d73921d9db739d747f82fe5568c82ad8c1982fef954c5ecb63d" origin="Generated by Gradle"/>
@ -2280,6 +2553,14 @@
<sha256 value="b82852b37ecedf8342eeee3cd69aae7658e0ed485ef7c2b0f2ba384dd223dd17" origin="Generated by Gradle"/> <sha256 value="b82852b37ecedf8342eeee3cd69aae7658e0ed485ef7c2b0f2ba384dd223dd17" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-transport-sctp" version="4.1.114.Final">
<artifact name="netty-transport-sctp-4.1.114.Final.jar"> <artifact name="netty-transport-sctp-4.1.114.Final.jar">
<sha256 value="5db192fb9c23615cf82862888c192f3ec98bae26410e1ac7ee40ecebe208e181" origin="Generated by Gradle"/> <sha256 value="5db192fb9c23615cf82862888c192f3ec98bae26410e1ac7ee40ecebe208e181" origin="Generated by Gradle"/>
@ -2288,6 +2569,14 @@
<sha256 value="95b0121474bc8938d7817cd969d345e04021cd77d60d7b3e9f5e875b426336bd" origin="Generated by Gradle"/> <sha256 value="95b0121474bc8938d7817cd969d345e04021cd77d60d7b3e9f5e875b426336bd" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.netty" name="netty-transport-udt" version="4.1.114.Final">
<artifact name="netty-transport-udt-4.1.114.Final.jar"> <artifact name="netty-transport-udt-4.1.114.Final.jar">
<sha256 value="2431ecd15cde787019de5aa0a48063e6d72758ff75e67ed5d0009f470f559009" origin="Generated by Gradle"/> <sha256 value="2431ecd15cde787019de5aa0a48063e6d72758ff75e67ed5d0009f470f559009" origin="Generated by Gradle"/>
@ -2296,6 +2585,14 @@
<sha256 value="faff00ad0c07c5316ce118b2a36276e03bb00feb2b86f4e80a351f417392cd1b" origin="Generated by Gradle"/> <sha256 value="faff00ad0c07c5316ce118b2a36276e03bb00feb2b86f4e80a351f417392cd1b" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </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"> <component group="io.opencensus" name="opencensus-api" version="0.31.1">
<artifact name="opencensus-api-0.31.1.jar"> <artifact name="opencensus-api-0.31.1.jar">
<sha256 value="f1474d47f4b6b001558ad27b952e35eda5cc7146788877fc52938c6eba24b382" origin="Generated by Gradle"/> <sha256 value="f1474d47f4b6b001558ad27b952e35eda5cc7146788877fc52938c6eba24b382" origin="Generated by Gradle"/>

@ -40,7 +40,8 @@ public class MetricCategoryRegistryImpl implements MetricCategoryRegistry {
* @param categoryEnum the category enum * @param categoryEnum the category enum
*/ */
public <T extends Enum<T> & MetricCategory> void addCategories(final Class<T> categoryEnum) { 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 { dependencies {
api platform('com.fasterxml.jackson:jackson-bom:2.18.0') api platform('com.fasterxml.jackson:jackson-bom:2.18.0')
api platform('io.grpc:grpc-bom:1.68.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.opentelemetry:opentelemetry-bom:1.43.0')
api platform('io.prometheus:simpleclient_bom:0.16.0') api platform('io.prometheus:simpleclient_bom:0.16.0')
api platform('io.vertx:vertx-stack-depchain:4.5.10') api platform('io.vertx:vertx-stack-depchain:4.5.10')
@ -43,8 +43,14 @@ dependencies {
api project(':acceptance-tests:dsl') api project(':acceptance-tests:dsl')
api project(':besu') api project(':besu')
api project(':config') api project(':config')
api project(':consensus:clique')
api project(':consensus:common')
api project(':consensus:ibft')
api project(':consensus:merge')
api project(':consensus:qbft')
api project(':crypto:algorithms') api project(':crypto:algorithms')
api project(':crypto:services') api project(':crypto:services')
api project(':datatypes')
api project(':ethereum:api') api project(':ethereum:api')
api project(':ethereum:blockcreation') api project(':ethereum:blockcreation')
api project(':ethereum:core') api project(':ethereum:core')
@ -53,9 +59,12 @@ dependencies {
api project(':ethereum:permissioning') api project(':ethereum:permissioning')
api project(':ethereum:referencetests') api project(':ethereum:referencetests')
api project(':ethereum:rlp') api project(':ethereum:rlp')
api project(':ethereum:trie')
api project(':evm') api project(':evm')
api project(':datatypes') api project(':metrics:core')
api project(':plugin-api') api project(':plugin-api')
api project(':testutil')
api project(':util')
api 'com.github.ben-manes.caffeine:caffeine:3.1.8' api 'com.github.ben-manes.caffeine:caffeine:3.1.8'

@ -264,7 +264,7 @@ public abstract class RocksDBColumnarKeyValueStorageTest extends AbstractKeyValu
List.of()); List.of());
store.close(); 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 = store =
createSegmentedStore( createSegmentedStore(
testPath, testPath,

@ -51,7 +51,6 @@ include 'ethereum:mock-p2p'
include 'ethereum:p2p' include 'ethereum:p2p'
include 'ethereum:permissioning' include 'ethereum:permissioning'
include 'ethereum:referencetests' include 'ethereum:referencetests'
include 'ethereum:retesteth'
include 'ethereum:rlp' include 'ethereum:rlp'
include 'ethereum:stratum' include 'ethereum:stratum'
include 'ethereum:ethstats' include 'ethereum:ethstats'

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

Loading…
Cancel
Save