diff --git a/CHANGELOG.md b/CHANGELOG.md index ea2535d6ba0..45ba4a00508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ ### Breaking Changes - Removed Retesteth rpc service and commands [#7833](https://github.com/hyperledger/besu/pull/7783) +- With the upgrade of the Prometheus Java Metrics library, there are the following changes: + - Gauge names are not allowed to end with `total`, therefore the metric `besu_blockchain_difficulty_total` is losing the `_total` suffix + - The `_created` timestamps are not returned by default, you can set the env var `BESU_OPTS="-Dio.prometheus.exporter.includeCreatedTimestamps=true"` to enable them + - Some JVM metrics have changed name to adhere to the OTEL standard (see the table below), [Besu Full Grafana dashboard](https://grafana.com/grafana/dashboards/16455-besu-full/) is updated to support both names + + | Old Name | New Name | + |---------------------------------|---------------------------------| + | jvm_memory_bytes_committed | jvm_memory_committed_bytes | + | jvm_memory_bytes_init | jvm_memory_init_bytes | + | jvm_memory_bytes_max | jvm_memory_max_bytes | + | jvm_memory_bytes_used | jvm_memory_used_bytes | + | jvm_memory_pool_bytes_committed | jvm_memory_pool_committed_bytes | + | jvm_memory_pool_bytes_init | jvm_memory_pool_init_bytes | + | jvm_memory_pool_bytes_max | jvm_memory_pool_max_bytes | + | jvm_memory_pool_bytes_used | jvm_memory_pool_used_bytes | ### Upcoming Breaking Changes - Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface. @@ -22,13 +37,17 @@ - Create and publish Besu BOM (Bill of Materials) [#7615](https://github.com/hyperledger/besu/pull/7615) - Update Java dependencies [#7786](https://github.com/hyperledger/besu/pull/7786) - Add a method to get all the transaction in the pool, to the `TransactionPoolService`, to easily access the transaction pool content from plugins [#7813](https://github.com/hyperledger/besu/pull/7813) +- Upgrade RocksDB JNI library from version 8.3.2 to 9.7.3 [#7817](https://github.com/hyperledger/besu/pull/7817) - Add a method to check if a metric category is enabled to the plugin API [#7832](https://github.com/hyperledger/besu/pull/7832) - Add a new metric collector for counters which get their value from suppliers [#7894](https://github.com/hyperledger/besu/pull/7894) - Add account and state overrides to `eth_call` [#7801](https://github.com/hyperledger/besu/pull/7801) and `eth_estimateGas` [#7890](https://github.com/hyperledger/besu/pull/7890) +- Prometheus Java Metrics library upgraded to version 1.3.3 [#7880](https://github.com/hyperledger/besu/pull/7880) +- Add histogram to Prometheus metrics system [#7944](https://github.com/hyperledger/besu/pull/7944) ### Bug fixes - Fix registering new metric categories from plugins [#7825](https://github.com/hyperledger/besu/pull/7825) - Fix CVE-2024-47535 [7878](https://github.com/hyperledger/besu/pull/7878) +- Fix QBFT prepared block based proposal validation [#7875](https://github.com/hyperledger/besu/pull/7875) ## 24.10.0 diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java index 6f9ed42828a..9effaff4d44 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java @@ -74,12 +74,14 @@ import org.hyperledger.besu.plugin.services.TransactionSelectionService; import org.hyperledger.besu.plugin.services.TransactionSimulationService; import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry; +import org.hyperledger.besu.plugin.services.mining.MiningService; import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBPlugin; import org.hyperledger.besu.plugin.services.transactionpool.TransactionPoolService; import org.hyperledger.besu.services.BesuConfigurationImpl; import org.hyperledger.besu.services.BesuEventsImpl; import org.hyperledger.besu.services.BesuPluginContextImpl; import org.hyperledger.besu.services.BlockchainServiceImpl; +import org.hyperledger.besu.services.MiningServiceImpl; import org.hyperledger.besu.services.PermissioningServiceImpl; import org.hyperledger.besu.services.PicoCLIOptionsImpl; import org.hyperledger.besu.services.PrivacyPluginServiceImpl; @@ -220,6 +222,8 @@ public void startNode(final BesuNode node) { besuPluginContext.addService( TransactionPoolService.class, new TransactionPoolServiceImpl(besuController.getTransactionPool())); + besuPluginContext.addService( + MiningService.class, new MiningServiceImpl(besuController.getMiningCoordinator())); component.rpcEndpointService().init(runner.getInProcessRpcMethods()); diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/BadCLIOptionsPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/BadCLIOptionsPlugin.java index ec048ea0d32..2bf826ec42e 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/BadCLIOptionsPlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/BadCLIOptionsPlugin.java @@ -16,8 +16,8 @@ import static java.nio.charset.StandardCharsets.UTF_8; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; -import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.PicoCLIOptions; import java.io.File; @@ -39,7 +39,8 @@ public class BadCLIOptionsPlugin implements BesuPlugin { private File callbackDir; @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { LOG.info("Registering BadCliOptionsPlugin"); callbackDir = new File(System.getProperty("besu.plugins.dir", "plugins")); writeStatus("init"); diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBesuEventsPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBesuEventsPlugin.java index 7a4a17cf711..7c218126d63 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBesuEventsPlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBesuEventsPlugin.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.plugins; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.data.BlockHeader; @@ -42,7 +43,8 @@ public class TestBesuEventsPlugin implements BesuPlugin { private File callbackDir; @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { this.context = context; LOG.info("Registered"); callbackDir = new File(System.getProperty("besu.plugins.dir", "plugins")); diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBlockchainServiceFinalizedPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBlockchainServiceFinalizedPlugin.java index 4984e7a00e8..29ccc83d8bb 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBlockchainServiceFinalizedPlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBlockchainServiceFinalizedPlugin.java @@ -17,8 +17,8 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; -import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.data.BlockContext; import org.hyperledger.besu.plugin.services.BlockchainService; import org.hyperledger.besu.plugin.services.RpcEndpointService; @@ -40,7 +40,8 @@ public class TestBlockchainServiceFinalizedPlugin implements BesuPlugin { private static final String RPC_METHOD_SAFE_BLOCK = "updateSafeBlockV1"; @Override - public void register(final ServiceManager serviceManager) { + @SuppressWarnings("removal") + public void register(final BesuContext serviceManager) { LOG.trace("Registering plugin ..."); final RpcEndpointService rpcEndpointService = diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.java index adbc1a35792..a304da09380 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.java @@ -15,8 +15,8 @@ package org.hyperledger.besu.tests.acceptance.plugins; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; -import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.PicoCLIOptions; import org.hyperledger.besu.plugin.services.RpcEndpointService; import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; @@ -36,7 +36,8 @@ public class TestInProcessRpcServicePlugin implements BesuPlugin { long minGasPrice = -1; @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { final PicoCLIOptions cmdlineOptions = context .getService(PicoCLIOptions.class) diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.java index 9400fb4bccd..8b731725225 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.plugins; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -33,7 +34,8 @@ public class TestMetricsPlugin implements BesuPlugin { private ServiceManager serviceManager; @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { LOG.info("Registering TestMetricsPlugin"); serviceManager = context; context diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPermissioningPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPermissioningPlugin.java index c2503ed8112..b41bcbc4a5f 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPermissioningPlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPermissioningPlugin.java @@ -14,8 +14,8 @@ */ package org.hyperledger.besu.tests.acceptance.plugins; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; -import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.PermissioningService; import org.hyperledger.besu.plugin.services.PicoCLIOptions; @@ -40,7 +40,8 @@ public class TestPermissioningPlugin implements BesuPlugin { PermissioningService service; @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { context.getService(PicoCLIOptions.class).orElseThrow().addPicoCLIOptions("permissioning", this); service = context.getService(PermissioningService.class).orElseThrow(); } diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPicoCLIPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPicoCLIPlugin.java index bb83ba676db..ec242fa4c68 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPicoCLIPlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPicoCLIPlugin.java @@ -14,8 +14,8 @@ */ package org.hyperledger.besu.tests.acceptance.plugins; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; -import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.PicoCLIOptions; import java.io.File; @@ -57,7 +57,8 @@ public class TestPicoCLIPlugin implements BesuPlugin { private File callbackDir; @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { LOG.info("Registering. Test Option is '{}'", testOption); state = "registering"; diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPrivacyServicePlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPrivacyServicePlugin.java index 698653f356f..15fc22a42fa 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPrivacyServicePlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPrivacyServicePlugin.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.plugins; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.PicoCLIOptions; @@ -40,7 +41,8 @@ public class TestPrivacyServicePlugin implements BesuPlugin { new TestSigningPrivateMarkerTransactionFactory(); @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { this.context = context; context diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestRpcEndpointServicePlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestRpcEndpointServicePlugin.java index 75d72473bf1..e4f0e8fdbd1 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestRpcEndpointServicePlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestRpcEndpointServicePlugin.java @@ -16,8 +16,8 @@ import static com.google.common.base.Preconditions.checkArgument; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; -import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.RpcEndpointService; import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest; @@ -51,7 +51,8 @@ private String throwException(final PluginRpcRequest request) { } @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { context .getService(RpcEndpointService.class) .ifPresent( diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index 06dca6c6f0a..0f398fae1eb 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -1034,8 +1034,7 @@ public Runner build() { subscriptionManager, privacyParameters, context.getBlockchain().getGenesisBlockHeader()); } - final Optional metricsService = - createMetricsService(vertx, metricsConfiguration); + final Optional metricsService = createMetricsService(metricsConfiguration); final Optional ethStatsService; if (isEthStatsEnabled()) { @@ -1469,9 +1468,8 @@ private WebSocketService createWebsocketService( vertx, configuration, websocketMessageHandler, authenticationService, metricsSystem); } - private Optional createMetricsService( - final Vertx vertx, final MetricsConfiguration configuration) { - return MetricsService.create(vertx, configuration, metricsSystem); + private Optional createMetricsService(final MetricsConfiguration configuration) { + return MetricsService.create(configuration, metricsSystem); } /** diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index c12b405e53f..e2c657dd18d 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -169,6 +169,7 @@ import org.hyperledger.besu.plugin.services.TransactionSimulationService; import org.hyperledger.besu.plugin.services.exception.StorageException; import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry; +import org.hyperledger.besu.plugin.services.mining.MiningService; import org.hyperledger.besu.plugin.services.p2p.P2PService; import org.hyperledger.besu.plugin.services.rlp.RlpConverterService; import org.hyperledger.besu.plugin.services.securitymodule.SecurityModule; @@ -181,6 +182,7 @@ import org.hyperledger.besu.services.BesuEventsImpl; import org.hyperledger.besu.services.BesuPluginContextImpl; import org.hyperledger.besu.services.BlockchainServiceImpl; +import org.hyperledger.besu.services.MiningServiceImpl; import org.hyperledger.besu.services.P2PServiceImpl; import org.hyperledger.besu.services.PermissioningServiceImpl; import org.hyperledger.besu.services.PicoCLIOptionsImpl; @@ -1276,6 +1278,7 @@ private void startPlugins(final Runner runner) { besuPluginContext.addService( SynchronizationService.class, new SynchronizationServiceImpl( + besuController.getSynchronizer(), besuController.getProtocolContext(), besuController.getProtocolSchedule(), besuController.getSyncState(), @@ -1301,6 +1304,9 @@ private void startPlugins(final Runner runner) { miningParametersSupplier.get()), besuController.getProtocolSchedule())); + besuPluginContext.addService( + MiningService.class, new MiningServiceImpl(besuController.getMiningCoordinator())); + besuController.getAdditionalPluginServices().appendPluginServices(besuPluginContext); besuPluginContext.startPlugins(); } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/PermissionsOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/PermissionsOptions.java index b6c744c98f7..0a2e9e967fc 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/PermissionsOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/PermissionsOptions.java @@ -56,32 +56,40 @@ public class PermissionsOptions { "Account permissioning config TOML file (default: a file named \"permissions_config.toml\" in the Besu data folder)") private String accountPermissionsConfigFile = null; + private static final String DEPRECATION_PREFIX = + "Deprecated. Onchain permissioning is deprecated. See CHANGELOG for alternative options. "; + @CommandLine.Option( names = {"--permissions-nodes-contract-address"}, - description = "Address of the node permissioning smart contract", + description = DEPRECATION_PREFIX + "Address of the node permissioning smart contract", arity = "1") private final Address permissionsNodesContractAddress = null; @CommandLine.Option( names = {"--permissions-nodes-contract-version"}, - description = "Version of the EEA Node Permissioning interface (default: ${DEFAULT-VALUE})") + description = + DEPRECATION_PREFIX + + "Version of the EEA Node Permissioning interface (default: ${DEFAULT-VALUE})") private final Integer permissionsNodesContractVersion = 1; @CommandLine.Option( names = {"--permissions-nodes-contract-enabled"}, - description = "Enable node level permissions via smart contract (default: ${DEFAULT-VALUE})") + description = + DEPRECATION_PREFIX + + "Enable node level permissions via smart contract (default: ${DEFAULT-VALUE})") private final Boolean permissionsNodesContractEnabled = false; @CommandLine.Option( names = {"--permissions-accounts-contract-address"}, - description = "Address of the account permissioning smart contract", + description = DEPRECATION_PREFIX + "Address of the account permissioning smart contract", arity = "1") private final Address permissionsAccountsContractAddress = null; @CommandLine.Option( names = {"--permissions-accounts-contract-enabled"}, description = - "Enable account level permissions via smart contract (default: ${DEFAULT-VALUE})") + DEPRECATION_PREFIX + + "Enable account level permissions via smart contract (default: ${DEFAULT-VALUE})") private final Boolean permissionsAccountsContractEnabled = false; /** Default constructor. */ @@ -151,6 +159,7 @@ public Optional permissioningConfiguration( SmartContractPermissioningConfiguration.createDefault(); if (Boolean.TRUE.equals(permissionsNodesContractEnabled)) { + logger.warn("Onchain (contract) node permissioning options are " + DEPRECATION_PREFIX); if (permissionsNodesContractAddress == null) { throw new CommandLine.ParameterException( commandLine, @@ -170,6 +179,7 @@ public Optional permissioningConfiguration( } if (Boolean.TRUE.equals(permissionsAccountsContractEnabled)) { + logger.warn("Onchain (contract) account permissioning options are " + DEPRECATION_PREFIX); if (permissionsAccountsContractAddress == null) { throw new CommandLine.ParameterException( commandLine, diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/blocks/BlocksSubCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/blocks/BlocksSubCommand.java index 95617fe8ca1..5862b11c19b 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/blocks/BlocksSubCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/blocks/BlocksSubCommand.java @@ -53,7 +53,6 @@ import java.util.function.Function; import java.util.function.Supplier; -import io.vertx.core.Vertx; import jakarta.validation.constraints.NotBlank; import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; @@ -458,8 +457,7 @@ private static Optional initMetrics(final BlocksSubCommand paren parentCommand.parentCommand.metricsConfiguration(); Optional metricsService = - MetricsService.create( - Vertx.vertx(), metricsConfiguration, parentCommand.parentCommand.getMetricsSystem()); + MetricsService.create(metricsConfiguration, parentCommand.parentCommand.getMetricsSystem()); metricsService.ifPresent(MetricsService::start); return metricsService; } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/RestoreState.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/RestoreState.java index 64803802405..47a6c2294a5 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/RestoreState.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/RestoreState.java @@ -34,9 +34,9 @@ import org.hyperledger.besu.ethereum.trie.Node; import org.hyperledger.besu.ethereum.trie.PersistVisitor; import org.hyperledger.besu.ethereum.trie.RestoreVisitor; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.forest.ForestWorldStateArchive; import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.util.io.RollingFileReader; import java.io.IOException; @@ -192,8 +192,8 @@ private void restoreAccounts() throws IOException { final Bytes accountRlp = accountInput.readBytes(); final Bytes code = accountInput.readBytes(); - final StateTrieAccountValue trieAccount = - StateTrieAccountValue.readFrom(new BytesValueRLPInput(accountRlp, false, true)); + final PmtStateTrieAccountValue trieAccount = + PmtStateTrieAccountValue.readFrom(new BytesValueRLPInput(accountRlp, false, true)); if (!trieAccount.getCodeHash().equals(Hash.hash(code))) { throw new RuntimeException("Code hash doesn't match"); } diff --git a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java index 831429a02f6..96de7a2af0c 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -625,7 +625,6 @@ public BesuController build() { ethereumWireProtocolConfiguration.isLegacyEth64ForkIdEnabled()); final EthPeers ethPeers = new EthPeers( - EthProtocol.NAME, currentProtocolSpecSupplier, clock, metricsSystem, diff --git a/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java index fbee90edef9..fdcf8554751 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkState; import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.BesuService; @@ -49,7 +50,8 @@ import org.slf4j.LoggerFactory; /** The Besu plugin context implementation. */ -public class BesuPluginContextImpl implements ServiceManager, PluginVersionsProvider { +@SuppressWarnings("removal") +public class BesuPluginContextImpl implements BesuContext, ServiceManager, PluginVersionsProvider { private static final Logger LOG = LoggerFactory.getLogger(BesuPluginContextImpl.class); diff --git a/besu/src/main/java/org/hyperledger/besu/services/MiningServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/MiningServiceImpl.java new file mode 100644 index 00000000000..1ee4355066f --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/services/MiningServiceImpl.java @@ -0,0 +1,49 @@ +/* + * 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.services; + +import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; +import org.hyperledger.besu.plugin.services.mining.MiningService; + +/** + * Implementation of the {@link MiningService} interface. This class provides methods to start and + * stop the mining process using a {@link MiningCoordinator}. + */ +public class MiningServiceImpl implements MiningService { + + private final MiningCoordinator miningCoordinator; + + /** + * Constructs a new {@code MiningServiceImpl} with the specified {@link MiningCoordinator}. + * + * @param miningCoordinator the mining coordinator to be used for starting and stopping the mining + * process + */ + public MiningServiceImpl(final MiningCoordinator miningCoordinator) { + this.miningCoordinator = miningCoordinator; + } + + /** Stops the mining process by delegating to the {@link MiningCoordinator}. */ + @Override + public void stop() { + miningCoordinator.stop(); + } + + /** Starts the mining process by delegating to the {@link MiningCoordinator}. */ + @Override + public void start() { + miningCoordinator.start(); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/services/SynchronizationServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/SynchronizationServiceImpl.java index 2e15e2ab82f..cd4f494dc65 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/SynchronizationServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/SynchronizationServiceImpl.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockImporter; +import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; @@ -45,6 +46,7 @@ public class SynchronizationServiceImpl implements SynchronizationService { private final ProtocolContext protocolContext; private final ProtocolSchedule protocolSchedule; + private final Synchronizer synchronizer; private final SyncState syncState; private final Optional worldStateArchive; @@ -52,16 +54,19 @@ public class SynchronizationServiceImpl implements SynchronizationService { /** * Constructor for SynchronizationServiceImpl. * + * @param synchronizer synchronizer * @param protocolContext protocol context * @param protocolSchedule protocol schedule * @param syncState sync state * @param worldStateArchive world state archive */ public SynchronizationServiceImpl( + final Synchronizer synchronizer, final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, final SyncState syncState, final WorldStateArchive worldStateArchive) { + this.synchronizer = synchronizer; this.protocolContext = protocolContext; this.protocolSchedule = protocolSchedule; this.syncState = syncState; @@ -157,4 +162,14 @@ public void disableWorldStateTrie() { } }); } + + @Override + public void stop() { + synchronizer.stop(); + } + + @Override + public void start() { + synchronizer.start(); + } } diff --git a/consensus/qbft/build.gradle b/consensus/qbft/build.gradle index 9675c4df89e..23e5576ebac 100644 --- a/consensus/qbft/build.gradle +++ b/consensus/qbft/build.gradle @@ -40,8 +40,6 @@ dependencies { implementation project(':ethereum:p2p') implementation project(':ethereum:rlp') implementation project(':evm') - implementation project(':pki') - implementation project(':services:kvstore') implementation 'com.google.guava:guava' implementation 'io.vertx:vertx-core' diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java index 10cdfa91501..54dab34bdf5 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java @@ -97,13 +97,37 @@ public MessageFactory getLocalNodeMessageFactory() { } public Block createBlockForProposalFromChainHead(final long timestamp) { - return createBlockForProposalFromChainHead(timestamp, finalState.getLocalAddress()); + return createBlockForProposalFromChainHead(timestamp, finalState.getLocalAddress(), 0); + } + + public Block createBlockForProposalFromChainHead(final long timestamp, final int roundNumber) { + return createBlockForProposalFromChainHead( + timestamp, finalState.getLocalAddress(), roundNumber); + } + + public Block createBlockForProposalFromChainHead(final long timestamp, final Address proposer) { + // this implies that EVERY block will have this node as the proposer :/ + return createBlockForProposal(blockchain.getChainHeadHeader(), timestamp, proposer, 0); + } + + public Block createBlockForProposalFromChainHead( + final long timestamp, final Address proposer, final int roundNumber) { + // this implies that EVERY block will have this node as the proposer :/ + return createBlockForProposal( + blockchain.getChainHeadHeader(), timestamp, proposer, roundNumber); } public Block createBlockForProposal( - final BlockHeader parent, final long timestamp, final Address proposer) { + final BlockHeader parent, + final long timestamp, + final Address proposer, + final int roundNumber) { final Block block = - finalState.getBlockCreatorFactory().create(0).createBlock(timestamp, parent).getBlock(); + finalState + .getBlockCreatorFactory() + .create(roundNumber) + .createBlock(timestamp, parent) + .getBlock(); final BlockHeaderBuilder headerBuilder = BlockHeaderBuilder.fromHeader(block.getHeader()); headerBuilder @@ -114,9 +138,9 @@ public Block createBlockForProposal( return new Block(newHeader, block.getBody()); } - public Block createBlockForProposalFromChainHead(final long timestamp, final Address proposer) { - // this implies that EVERY block will have this node as the proposer :/ - return createBlockForProposal(blockchain.getChainHeadHeader(), timestamp, proposer); + public Block createBlockForProposal( + final BlockHeader parent, final long timestamp, final Address proposer) { + return createBlockForProposal(parent, timestamp, proposer, 0); } public RoundSpecificPeers roundSpecificPeers(final ConsensusRoundIdentifier roundId) { diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/RoundChangeTest.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/RoundChangeTest.java index be439e4c1ec..b1464efd53b 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/RoundChangeTest.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/RoundChangeTest.java @@ -144,7 +144,8 @@ public void roundChangeHasPopulatedCertificateIfQuorumPrepareMessagesAndProposal public void whenSufficientRoundChangeMessagesAreReceivedForNewRoundLocalNodeCreatesProposalMsg() { // Note: Round-4 is the next round for which the local node is Proposer final ConsensusRoundIdentifier targetRound = new ConsensusRoundIdentifier(1, 4); - final Block locallyProposedBlock = context.createBlockForProposalFromChainHead(blockTimeStamp); + final Block locallyProposedBlock = + context.createBlockForProposalFromChainHead(blockTimeStamp, 4); final RoundChange rc1 = peers.getNonProposing(0).injectRoundChange(targetRound, empty()); final RoundChange rc2 = peers.getNonProposing(1).injectRoundChange(targetRound, empty()); @@ -177,14 +178,14 @@ public void proposalMessageContainsBlockOnWhichPeerPrepared() { context, new ConsensusRoundIdentifier(1, 1), context.createBlockForProposalFromChainHead( - ARBITRARY_BLOCKTIME / 2, peers.getProposer().getNodeAddress())); + ARBITRARY_BLOCKTIME / 2, peers.getProposer().getNodeAddress(), 1)); final PreparedCertificate bestPrepCert = createValidPreparedCertificate( context, new ConsensusRoundIdentifier(1, 2), context.createBlockForProposalFromChainHead( - ARBITRARY_BLOCKTIME, peers.getProposer().getNodeAddress())); + ARBITRARY_BLOCKTIME, peers.getProposer().getNodeAddress(), 2)); final ConsensusRoundIdentifier targetRound = new ConsensusRoundIdentifier(1, 4); @@ -206,7 +207,7 @@ public void proposalMessageContainsBlockOnWhichPeerPrepared() { // round number. final Block expectedBlockToPropose = context.createBlockForProposalFromChainHead( - ARBITRARY_BLOCKTIME, peers.getProposer().getNodeAddress()); + ARBITRARY_BLOCKTIME, peers.getProposer().getNodeAddress(), 4); final Proposal expectedProposal = localNodeMessageFactory.createProposal( @@ -234,7 +235,8 @@ public void cannotRoundChangeToAnEarlierRound() { final ConsensusRoundIdentifier priorRound = new ConsensusRoundIdentifier(1, 4); peers.roundChange(priorRound); - final Block locallyProposedBlock = context.createBlockForProposalFromChainHead(blockTimeStamp); + final Block locallyProposedBlock = + context.createBlockForProposalFromChainHead(blockTimeStamp, 9); final Proposal expectedProposal = localNodeMessageFactory.createProposal( @@ -271,7 +273,7 @@ public void subsequentRoundChangeMessagesFromPeerDoNotOverwritePriorMessage() { context, new ConsensusRoundIdentifier(1, 2), context.createBlockForProposalFromChainHead( - ARBITRARY_BLOCKTIME, peers.getProposer().getNodeAddress())); + ARBITRARY_BLOCKTIME, peers.getProposer().getNodeAddress(), 2)); final List> roundChangeMessages = Lists.newArrayList(); // Create a roundChange containing a PreparedCertificate @@ -288,7 +290,7 @@ public void subsequentRoundChangeMessagesFromPeerDoNotOverwritePriorMessage() { final Block expectedBlockToPropose = context.createBlockForProposalFromChainHead( - ARBITRARY_BLOCKTIME, peers.getProposer().getNodeAddress()); + ARBITRARY_BLOCKTIME, peers.getProposer().getNodeAddress(), 4); final Proposal expectedProposal = localNodeMessageFactory.createProposal( diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java index e0a8cb1c726..64f23cef279 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java @@ -160,9 +160,18 @@ public void startRoundWith( } else { LOG.debug( "Sending proposal from PreparedCertificate. round={}", roundState.getRoundIdentifier()); - blockToPublish = bestPreparedCertificate.get().getBlock(); + Block preparedBlock = bestPreparedCertificate.get().getBlock(); + final BftBlockInterface bftBlockInterface = + protocolContext.getConsensusContext(BftContext.class).getBlockInterface(); + blockToPublish = + bftBlockInterface.replaceRoundInBlock( + preparedBlock, + roundState.getRoundIdentifier().getRoundNumber(), + BftBlockHeaderFunctions.forCommittedSeal(bftExtraDataCodec)); } + LOG.debug(" proposal - new/prepared block hash : {}", blockToPublish.getHash()); + updateStateWithProposalAndTransmit( blockToPublish, roundChangeArtifacts.getRoundChanges(), @@ -202,8 +211,9 @@ protected void updateStateWithProposalAndTransmit( proposal.getSignedPayload().getPayload().getProposedBlock(), roundChanges, prepares); - updateStateWithProposedBlock(proposal); - sendPrepare(block); + if (updateStateWithProposedBlock(proposal)) { + sendPrepare(block); + } } /** diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java index 30253300096..6383945bcdf 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java @@ -99,7 +99,8 @@ public QbftRound createNewRound(final BlockHeader parentHeader, final int round) */ public QbftRound createNewRoundWithState( final BlockHeader parentHeader, final RoundState roundState) { - final BlockCreator blockCreator = blockCreatorFactory.create(0); + final BlockCreator blockCreator = + blockCreatorFactory.create(roundState.getRoundIdentifier().getRoundNumber()); // TODO(tmm): Why is this created everytime?! final QbftMessageTransmitter messageTransmitter = diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java index 81cbffdff96..bc3f1bb205c 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java @@ -137,6 +137,13 @@ private boolean validateProposalAndRoundChangeAreConsistent(final Proposal propo final PreparedRoundMetadata metadata = roundChangeWithLatestPreparedRound.get().getPayload().getPreparedRoundMetadata().get(); + LOG.debug( + "Prepared Metadata blockhash : {}, proposal blockhash: {}, prepared round in message: {}, proposal round in message: {}", + metadata.getPreparedBlockHash(), + proposal.getBlock().getHash(), + metadata.getPreparedRound(), + proposal.getRoundIdentifier().getRoundNumber()); + // The Hash in the roundchange/proposals is NOT the same as the value in the // prepares/roundchanges // as said payloads reference the block with an OLD round number in it - therefore, need @@ -155,8 +162,10 @@ private boolean validateProposalAndRoundChangeAreConsistent(final Proposal propo if (!metadata.getPreparedBlockHash().equals(expectedPriorBlockHash)) { LOG.info( - "{}: Latest Prepared Metadata blockhash does not align with proposed block", - ERROR_PREFIX); + "{}: Latest Prepared Metadata blockhash does not align with proposed block. Expected: {}, Actual: {}", + ERROR_PREFIX, + expectedPriorBlockHash, + metadata.getPreparedBlockHash()); return false; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetrics.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetrics.java index b5c74245ce4..c3eb1906f30 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetrics.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetrics.java @@ -50,9 +50,9 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { private void addObservation( final Map observations, final Observation observation) { final Map categoryObservations = - getNextMapLevel(observations, observation.getCategory().getName()); - if (observation.getLabels().isEmpty()) { - categoryObservations.put(observation.getMetricName(), observation.getValue()); + getNextMapLevel(observations, observation.category().getName()); + if (observation.labels().isEmpty()) { + categoryObservations.put(observation.metricName(), observation.value()); } else { addLabelledObservation(categoryObservations, observation); } @@ -60,12 +60,12 @@ private void addObservation( private void addLabelledObservation( final Map categoryObservations, final Observation observation) { - final List labels = observation.getLabels(); - Map values = getNextMapLevel(categoryObservations, observation.getMetricName()); + final List labels = observation.labels(); + Map values = getNextMapLevel(categoryObservations, observation.metricName()); for (int i = 0; i < labels.size() - 1; i++) { values = getNextMapLevel(values, labels.get(i)); } - values.put(labels.get(labels.size() - 1), observation.getValue()); + values.put(labels.get(labels.size() - 1), observation.value()); } @SuppressWarnings("unchecked") diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/DisabledPrivacyRpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/DisabledPrivacyRpcMethod.java index d51d32a1d4b..04e7dd4067b 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/DisabledPrivacyRpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/DisabledPrivacyRpcMethod.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +@Deprecated(since = "24.11.0") public class DisabledPrivacyRpcMethod implements JsonRpcMethod { private final String methodName; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyRpcMethodDecorator.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyRpcMethodDecorator.java index 823c8b13cfa..3f7a87c7f45 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyRpcMethodDecorator.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyRpcMethodDecorator.java @@ -27,6 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class MultiTenancyRpcMethodDecorator implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(MultiTenancyRpcMethodDecorator.class); private final JsonRpcMethod rpcMethod; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyUserUtil.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyUserUtil.java index 871d3fa577c..54daee347dc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyUserUtil.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyUserUtil.java @@ -18,6 +18,7 @@ import io.vertx.ext.auth.User; +@Deprecated(since = "24.11.0") public class MultiTenancyUserUtil { private static final String PRIVACY_USER_ID_CLAIM = "privacyUserId"; private static final String ENCLAVE_PRIVACY_PUBLIC_KEY_CLAIM = "privacyPublicKey"; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java index 4ef7e0aa1c3..9175464fe2e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java @@ -31,6 +31,7 @@ import java.util.List; +@Deprecated(since = "24.11.0") public class PrivGetFilterChanges implements JsonRpcMethod { private final PrivacyController privacyController; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java index ea6a5894a33..bf497d41aab 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java @@ -31,6 +31,7 @@ import java.util.List; +@Deprecated(since = "24.11.0") public class PrivGetFilterLogs implements JsonRpcMethod { private final PrivacyController privacyController; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java index eb41a1dad4e..aeaa2613b08 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java @@ -26,6 +26,7 @@ import org.hyperledger.besu.ethereum.privacy.MultiTenancyPrivacyController; import org.hyperledger.besu.ethereum.privacy.PrivacyController; +@Deprecated(since = "24.11.0") public class PrivUninstallFilter implements JsonRpcMethod { private final FilterManager filterManager; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivacyIdProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivacyIdProvider.java index 5f01bae059b..d59a64b0bab 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivacyIdProvider.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivacyIdProvider.java @@ -23,6 +23,7 @@ import io.vertx.ext.auth.User; @FunctionalInterface +@Deprecated(since = "24.11.0") public interface PrivacyIdProvider { String getPrivacyUserId(Optional user); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java index e96a08eb7d4..b8e78621ef2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java @@ -48,6 +48,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public abstract class AbstractEeaSendRawTransaction implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(AbstractEeaSendRawTransaction.class); private final TransactionPool transactionPool; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/JsonRpcErrorResponseException.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/JsonRpcErrorResponseException.java index 79d006f48e6..7b22ebcef1d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/JsonRpcErrorResponseException.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/JsonRpcErrorResponseException.java @@ -16,6 +16,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +@Deprecated(since = "24.11.0") public class JsonRpcErrorResponseException extends RuntimeException { private final RpcErrorType jsonRpcError; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/PluginEeaSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/PluginEeaSendRawTransaction.java index c81c0852e0a..513d0fa351f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/PluginEeaSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/PluginEeaSendRawTransaction.java @@ -33,6 +33,7 @@ import io.vertx.ext.auth.User; import org.apache.tuweni.bytes.Bytes; +@Deprecated(since = "24.11.0") public class PluginEeaSendRawTransaction extends AbstractEeaSendRawTransaction { private final PrivacyController privacyController; private final PrivacyIdProvider privacyIdProvider; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/RestrictedFlexibleEeaSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/RestrictedFlexibleEeaSendRawTransaction.java index 3fa12563c03..6c300fbc301 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/RestrictedFlexibleEeaSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/RestrictedFlexibleEeaSendRawTransaction.java @@ -37,6 +37,7 @@ import io.vertx.ext.auth.User; import org.apache.tuweni.bytes.Bytes; +@Deprecated(since = "24.11.0") public class RestrictedFlexibleEeaSendRawTransaction extends AbstractEeaSendRawTransaction { private final PrivacyController privacyController; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/RestrictedOffchainEeaSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/RestrictedOffchainEeaSendRawTransaction.java index 34b46973913..de467e31bcc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/RestrictedOffchainEeaSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/RestrictedOffchainEeaSendRawTransaction.java @@ -35,6 +35,7 @@ import io.vertx.ext.auth.User; import org.apache.tuweni.bytes.Bytes; +@Deprecated(since = "24.11.0") public class RestrictedOffchainEeaSendRawTransaction extends AbstractEeaSendRawTransaction { final PrivacyController privacyController; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/AbstractPrivateTraceByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/AbstractPrivateTraceByHash.java index 01398868624..209d5bf3bf4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/AbstractPrivateTraceByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/AbstractPrivateTraceByHash.java @@ -41,6 +41,7 @@ import java.util.function.Supplier; import java.util.stream.Stream; +@Deprecated(since = "24.11.0") public abstract class AbstractPrivateTraceByHash implements JsonRpcMethod { protected final Supplier blockTracerSupplier; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java index 5d9edc63b9d..5be9a9f2ab6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; +@Deprecated(since = "24.11.0") public class PrivCall extends AbstractBlockParameterMethod { private final PrivacyIdProvider privacyIdProvider; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java index 568125a2762..09ff5b19f96 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java @@ -32,6 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivCreatePrivacyGroup implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivCreatePrivacyGroup.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java index dc0fc90f661..d8c411c0853 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java @@ -39,6 +39,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivDebugGetStateRoot extends AbstractBlockParameterMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivDebugGetStateRoot.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java index 61b7791b3c0..73849eb92e5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java @@ -32,6 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivDeletePrivacyGroup implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivDeletePrivacyGroup.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java index aac4df3d2c9..7375590d55c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java @@ -48,6 +48,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivDistributeRawTransaction implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivDistributeRawTransaction.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java index 7e823232237..e41728b044e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java @@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory; @SuppressWarnings("MockNotUsedInProduction") +@Deprecated(since = "24.11.0") public class PrivFindPrivacyGroup implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivFindPrivacyGroup.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java index 7042d357f12..da3179834f0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java @@ -28,6 +28,7 @@ import org.apache.tuweni.bytes.Bytes; +@Deprecated(since = "24.11.0") public class PrivGetCode extends AbstractBlockParameterMethod { private final PrivacyController privacyController; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java index 9f231f41c06..e35ad79da77 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java @@ -42,6 +42,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivGetEeaTransactionCount implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivGetEeaTransactionCount.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java index 6947ea5e546..735eb9bf9d9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java @@ -38,6 +38,7 @@ import java.util.List; import java.util.Optional; +@Deprecated(since = "24.11.0") public class PrivGetLogs implements JsonRpcMethod { private final BlockchainQueries blockchainQueries; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddress.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddress.java index 816ed1c5da8..46e52525bea 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddress.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddress.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.core.PrivacyParameters; +@Deprecated(since = "24.11.0") public class PrivGetPrivacyPrecompileAddress implements JsonRpcMethod { private final Address privacyAddress; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java index 8779181599e..4419b82d50e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java @@ -38,6 +38,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivGetPrivateTransaction implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivGetPrivateTransaction.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java index d8757dc2fbd..fc547e88640 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java @@ -34,6 +34,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivGetTransactionCount implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivGetTransactionCount.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java index 287793ddc01..b7c7f25b4dd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java @@ -43,6 +43,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivGetTransactionReceipt implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivGetTransactionReceipt.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java index 49fc11f4b82..bd2ece37b94 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.privacy.MultiTenancyPrivacyController; import org.hyperledger.besu.ethereum.privacy.PrivacyController; +@Deprecated(since = "24.11.0") public class PrivNewFilter implements JsonRpcMethod { private final FilterManager filterManager; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java index 07d663bef55..f044b39f774 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java @@ -43,6 +43,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivTraceTransaction extends AbstractPrivateTraceByHash implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(TraceTransaction.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUtil.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUtil.java index 8db4b73bdb4..a3ca662fd12 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUtil.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUtil.java @@ -20,6 +20,7 @@ import java.util.Optional; +@Deprecated(since = "24.11.0") public class PrivUtil { public static void checkMembershipForAuthenticatedUser( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java index 0a66d1aa73b..925dc4ec65d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java @@ -36,6 +36,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Deprecated(since = "24.11.0") public class PrivxFindFlexiblePrivacyGroup implements JsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(PrivxFindFlexiblePrivacyGroup.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindOnchainPrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindOnchainPrivacyGroup.java index e09c72464e2..015c7728596 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindOnchainPrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindOnchainPrivacyGroup.java @@ -19,7 +19,7 @@ import org.hyperledger.besu.ethereum.privacy.PrivacyController; // Use PrivxFindFlexiblePrivacyGroup instead -@Deprecated +@Deprecated(since = "21.10.3") public class PrivxFindOnchainPrivacyGroup extends PrivxFindFlexiblePrivacyGroup { public PrivxFindOnchainPrivacyGroup( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/parameters/CreatePrivacyGroupParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/parameters/CreatePrivacyGroupParameter.java index f826ef179d4..c66f754d203 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/parameters/CreatePrivacyGroupParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/parameters/CreatePrivacyGroupParameter.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +@Deprecated(since = "24.11.0") public class CreatePrivacyGroupParameter { private final List addresses; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/PeerResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/PeerResult.java index 1bc2283acc3..99b7688c980 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/PeerResult.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/PeerResult.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results; +import org.hyperledger.besu.ethereum.eth.EthProtocol; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; @@ -52,7 +53,7 @@ static PeerResult fromEthPeer(final EthPeer peer) { connection.inboundInitiated())) .port(Quantity.create(peerInfo.getPort())) .id(peerInfo.getNodeId().toString()) - .protocols(Map.of(peer.getProtocolName(), ProtocolsResult.fromEthPeer(peer))) + .protocols(Map.of(EthProtocol.NAME, ProtocolsResult.fromEthPeer(peer))) .enode(connection.getRemoteEnode().toString()) .build(); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/proof/GetProofResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/proof/GetProofResult.java index f4adb7b0fed..e2ec8df4bac 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/proof/GetProofResult.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/proof/GetProofResult.java @@ -18,7 +18,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.proof.WorldStateProof; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import java.util.ArrayList; import java.util.List; @@ -64,7 +64,8 @@ public GetProofResult( public static GetProofResult buildGetProofResult( final Address address, final WorldStateProof worldStateProof) { - final StateTrieAccountValue stateTrieAccountValue = worldStateProof.getStateTrieAccountValue(); + final PmtStateTrieAccountValue stateTrieAccountValue = + worldStateProof.getStateTrieAccountValue(); final List storageEntries = new ArrayList<>(); worldStateProof diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java index 8ae62741b94..48d1dccee90 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java @@ -46,6 +46,7 @@ import java.util.Map; +@Deprecated(since = "24.11.0") public class PrivJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods { private final FilterManager filterManager; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethods.java index 304a36a677b..e648febc379 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethods.java @@ -42,6 +42,7 @@ import java.util.Optional; import java.util.stream.Collectors; +@Deprecated(since = "24.11.0") public abstract class PrivacyApiGroupJsonRpcMethods extends ApiGroupJsonRpcMethods { private final BlockchainQueries blockchainQueries; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/StateBackupService.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/StateBackupService.java index 63f51016498..27d96a1be93 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/StateBackupService.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/StateBackupService.java @@ -29,9 +29,9 @@ import org.hyperledger.besu.ethereum.trie.Node; import org.hyperledger.besu.ethereum.trie.TrieIterator; import org.hyperledger.besu.ethereum.trie.TrieIterator.State; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.util.io.RollingFileWriter; import java.io.IOException; @@ -241,8 +241,8 @@ private TrieIterator.State visitAccount(final Bytes32 nodeKey, final Node backupStatus.currentAccount = nodeKey; final Bytes nodeValue = node.getValue().orElse(Hash.EMPTY); - final StateTrieAccountValue account = - StateTrieAccountValue.readFrom(new BytesValueRLPInput(nodeValue, false)); + final PmtStateTrieAccountValue account = + PmtStateTrieAccountValue.readFrom(new BytesValueRLPInput(nodeValue, false)); final Bytes code = worldStateKeyValueStorage.getCode(account.getCodeHash()).orElse(Bytes.EMPTY); backupStatus.codeSize.addAndGet(code.size()); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java index 4a03b2eb938..50d13b3d506 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java @@ -74,7 +74,6 @@ public void getPeers() throws Exception { peerList.add( new EthPeer( MockPeerConnection.create(info1, addr60301, addr30302), - "eth", c -> {}, List.of(), EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE, @@ -84,7 +83,6 @@ public void getPeers() throws Exception { peerList.add( new EthPeer( MockPeerConnection.create(info2, addr30301, addr60302), - "eth", c -> {}, List.of(), EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE, @@ -94,7 +92,6 @@ public void getPeers() throws Exception { peerList.add( new EthPeer( MockPeerConnection.create(info3, addr30301, addr60303), - "eth", c -> {}, List.of(), EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminPeersTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminPeersTest.java index 1835a498835..5eef2f3d579 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminPeersTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminPeersTest.java @@ -120,7 +120,6 @@ private Collection peerList() { final EthPeer ethPeer = new EthPeer( p, - "eth", c -> {}, List.of(), EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java index a346cd827b2..69af2b85ac0 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java @@ -42,7 +42,7 @@ import org.hyperledger.besu.ethereum.core.MiningConfiguration; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.proof.WorldStateProof; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import java.util.Collections; @@ -202,7 +202,7 @@ private GetProofResult generateWorldState() { when(blockchainQueries.getWorldStateArchive()).thenReturn(archive); - final StateTrieAccountValue stateTrieAccountValue = mock(StateTrieAccountValue.class); + final PmtStateTrieAccountValue stateTrieAccountValue = mock(PmtStateTrieAccountValue.class); when(stateTrieAccountValue.getBalance()).thenReturn(balance); when(stateTrieAccountValue.getCodeHash()).thenReturn(codeHash); when(stateTrieAccountValue.getNonce()).thenReturn(nonce); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java index f6e06f82d2e..8a354638f01 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java @@ -183,7 +183,7 @@ private void createGauges(final MetricsSystem metricsSystem) { metricsSystem.createGauge( BLOCKCHAIN, - "difficulty_total", + "difficulty", "Total difficulty of the chainhead", () -> this.getChainHead().getTotalDifficulty().toBigInteger().doubleValue()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/proof/WorldStateProof.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/proof/WorldStateProof.java index 91c492e69c1..8853dc23716 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/proof/WorldStateProof.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/proof/WorldStateProof.java @@ -16,7 +16,7 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.Proof; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import java.util.ArrayList; import java.util.List; @@ -29,14 +29,14 @@ public class WorldStateProof { - private final StateTrieAccountValue stateTrieAccountValue; + private final PmtStateTrieAccountValue stateTrieAccountValue; private final Proof accountProof; private final Map> storageProofs; public WorldStateProof( - final StateTrieAccountValue stateTrieAccountValue, + final PmtStateTrieAccountValue stateTrieAccountValue, final Proof accountProof, final SortedMap> storageProofs) { this.stateTrieAccountValue = stateTrieAccountValue; @@ -44,7 +44,7 @@ public WorldStateProof( this.storageProofs = storageProofs; } - public StateTrieAccountValue getStateTrieAccountValue() { + public PmtStateTrieAccountValue getStateTrieAccountValue() { return stateTrieAccountValue; } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/proof/WorldStateProofProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/proof/WorldStateProofProvider.java index 1f49dea273c..a858f1a9029 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/proof/WorldStateProofProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/proof/WorldStateProofProvider.java @@ -22,10 +22,10 @@ import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.ethereum.trie.Proof; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.patricia.RemoveVisitor; import org.hyperledger.besu.ethereum.trie.patricia.SimpleMerklePatriciaTrie; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import java.util.Comparator; @@ -73,7 +73,7 @@ public Optional getAccountProof( return accountProof .getValue() .map(RLP::input) - .map(StateTrieAccountValue::readFrom) + .map(PmtStateTrieAccountValue::readFrom) .map( account -> { final SortedMap> storageProofs = @@ -85,7 +85,7 @@ public Optional getAccountProof( private SortedMap> getStorageProofs( final Hash accountHash, - final StateTrieAccountValue account, + final PmtStateTrieAccountValue account, final List accountStorageKeys) { final MerkleTrie storageTrie = newAccountStorageTrie(accountHash, account.getStorageRoot()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/AbstractStateTrieAccountValue.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/AbstractStateTrieAccountValue.java new file mode 100644 index 00000000000..805aef9b44d --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/AbstractStateTrieAccountValue.java @@ -0,0 +1,81 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie.common; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.hyperledger.besu.datatypes.AccountValue; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.rlp.RLPOutput; + +/** Represents the raw values associated with an account in the world state trie. */ +public abstract class AbstractStateTrieAccountValue implements AccountValue { + + protected final long nonce; + protected final Wei balance; + protected final Hash codeHash; + + public AbstractStateTrieAccountValue(final long nonce, final Wei balance, final Hash codeHash) { + checkNotNull(balance, "balance cannot be null"); + checkNotNull(codeHash, "codeHash cannot be null"); + this.nonce = nonce; + this.balance = balance; + this.codeHash = codeHash; + } + + /** + * The account nonce, that is the number of transactions sent from that account. + * + * @return the account nonce. + */ + @Override + public long getNonce() { + return nonce; + } + + /** + * The available balance of that account. + * + * @return the balance, in Wei, of the account. + */ + @Override + public Wei getBalance() { + return balance; + } + + /** + * The hash of the EVM bytecode associated with this account. + * + * @return the hash of the account code (which may be {@link Hash#EMPTY}). + */ + @Override + public Hash getCodeHash() { + return codeHash; + } + + /** + * The hash of the root of the storage trie associated with this account. + * + * @return the hash of the root node of the storage trie. + */ + @Override + public Hash getStorageRoot() { + return Hash.EMPTY_TRIE_HASH; + } + + @Override + public abstract void writeTo(final RLPOutput out); +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/StateTrieAccountValue.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/PmtStateTrieAccountValue.java similarity index 64% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/StateTrieAccountValue.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/PmtStateTrieAccountValue.java index 40c420f7518..5a291846eab 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/StateTrieAccountValue.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/PmtStateTrieAccountValue.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.ethereum.worldstate; +package org.hyperledger.besu.ethereum.trie.common; import static com.google.common.base.Preconditions.checkNotNull; @@ -26,43 +26,17 @@ import org.apache.tuweni.bytes.Bytes32; -/** Represents the raw values associated with an account in the world state trie. */ -public class StateTrieAccountValue implements AccountValue { +/** Represents the raw values associated with an account in the world state patricia merkle trie. */ +public class PmtStateTrieAccountValue extends AbstractStateTrieAccountValue + implements AccountValue { - protected final long nonce; - protected final Wei balance; protected final Hash storageRoot; - protected final Hash codeHash; - public StateTrieAccountValue( + public PmtStateTrieAccountValue( final long nonce, final Wei balance, final Hash storageRoot, final Hash codeHash) { - checkNotNull(balance, "balance cannot be null"); + super(nonce, balance, codeHash); checkNotNull(storageRoot, "storageRoot cannot be null"); - checkNotNull(codeHash, "codeHash cannot be null"); - this.nonce = nonce; - this.balance = balance; this.storageRoot = storageRoot; - this.codeHash = codeHash; - } - - /** - * The account nonce, that is the number of transactions sent from that account. - * - * @return the account nonce. - */ - @Override - public long getNonce() { - return nonce; - } - - /** - * The available balance of that account. - * - * @return the balance, in Wei, of the account. - */ - @Override - public Wei getBalance() { - return balance; } /** @@ -75,25 +49,15 @@ public Hash getStorageRoot() { return storageRoot; } - /** - * The hash of the EVM bytecode associated with this account. - * - * @return the hash of the account code (which may be {@link Hash#EMPTY}). - */ - @Override - public Hash getCodeHash() { - return codeHash; - } - @Override public boolean equals(final Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - final StateTrieAccountValue that = (StateTrieAccountValue) o; + PmtStateTrieAccountValue that = (PmtStateTrieAccountValue) o; return nonce == that.nonce - && balance.equals(that.balance) - && storageRoot.equals(that.storageRoot) - && codeHash.equals(that.codeHash); + && Objects.equals(balance, that.balance) + && Objects.equals(storageRoot, that.storageRoot) + && Objects.equals(codeHash, that.codeHash); } @Override @@ -109,11 +73,10 @@ public void writeTo(final RLPOutput out) { out.writeUInt256Scalar(balance); out.writeBytes(storageRoot); out.writeBytes(codeHash); - out.endList(); } - public static StateTrieAccountValue readFrom(final RLPInput in) { + public static PmtStateTrieAccountValue readFrom(final RLPInput in) { in.enterList(); final long nonce = in.readLongScalar(); @@ -132,9 +95,9 @@ public static StateTrieAccountValue readFrom(final RLPInput in) { } else { codeHash = in.readBytes32(); } - in.leaveList(); - return new StateTrieAccountValue(nonce, balance, Hash.wrap(storageRoot), Hash.wrap(codeHash)); + return new PmtStateTrieAccountValue( + nonce, balance, Hash.wrap(storageRoot), Hash.wrap(codeHash)); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java index 1e2f62addbb..afbb1e05816 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.rlp.RLP; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoader; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedWorldStorageManager; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; @@ -26,7 +27,6 @@ import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogManager; import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldStateConfig; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.plugin.ServiceManager; @@ -120,7 +120,7 @@ public void prepareStateHealing(final Address address, final Bytes location) { accountTrie .get(accountHash) .map(RLP::input) - .map(StateTrieAccountValue::readFrom) + .map(PmtStateTrieAccountValue::readFrom) .ifPresent( account -> { final StoredMerklePatriciaTrie storageTrie = diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java index 07ded9ddf61..e712c66eadc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java @@ -24,13 +24,13 @@ import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; import org.hyperledger.besu.ethereum.trie.MerkleTrie; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFlatDbStrategy; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFlatDbStrategyProvider; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategy; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.evm.account.AccountStorageEntry; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -135,7 +135,7 @@ public Optional getStorageValueByStorageSlotKey( getAccount(accountHash) .map( b -> - StateTrieAccountValue.readFrom( + PmtStateTrieAccountValue.readFrom( org.hyperledger.besu.ethereum.rlp.RLP.input(b)) .getStorageRoot()), accountHash, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogFactoryImpl.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogFactoryImpl.java index e99b5109649..d528373d24d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogFactoryImpl.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogFactoryImpl.java @@ -22,9 +22,9 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.rlp.RLPOutput; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.common.DiffBasedValue; import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogLayer; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.plugin.data.BlockHeader; import org.hyperledger.besu.plugin.services.trielogs.TrieLog; import org.hyperledger.besu.plugin.services.trielogs.TrieLogAccumulator; @@ -160,8 +160,10 @@ public static TrieLogLayer readFrom(final RLPInput input) { input.skipNext(); } else { input.enterList(); - final StateTrieAccountValue oldValue = nullOrValue(input, StateTrieAccountValue::readFrom); - final StateTrieAccountValue newValue = nullOrValue(input, StateTrieAccountValue::readFrom); + final PmtStateTrieAccountValue oldValue = + nullOrValue(input, PmtStateTrieAccountValue::readFrom); + final PmtStateTrieAccountValue newValue = + nullOrValue(input, PmtStateTrieAccountValue::readFrom); final boolean isCleared = getOptionalIsCleared(input); input.leaveList(); newLayer diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/forest/worldview/ForestMutableWorldState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/forest/worldview/ForestMutableWorldState.java index d94f3564126..360dabb0c6d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/forest/worldview/ForestMutableWorldState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/forest/worldview/ForestMutableWorldState.java @@ -23,9 +23,9 @@ import org.hyperledger.besu.ethereum.rlp.RLPException; import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.trie.MerkleTrie; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage; import org.hyperledger.besu.evm.account.Account; @@ -137,7 +137,7 @@ public Account get(final Address address) { private WorldStateAccount deserializeAccount( final Address address, final Hash addressHash, final Bytes encoded) throws RLPException { final RLPInput in = RLP.input(encoded); - final StateTrieAccountValue accountValue = StateTrieAccountValue.readFrom(in); + final PmtStateTrieAccountValue accountValue = PmtStateTrieAccountValue.readFrom(in); return new WorldStateAccount(address, addressHash, accountValue); } @@ -224,13 +224,15 @@ protected class WorldStateAccount implements Account { private final Address address; private final Hash addressHash; - final StateTrieAccountValue accountValue; + final PmtStateTrieAccountValue accountValue; // Lazily initialized since we don't always access storage. private volatile MerkleTrie storageTrie; private WorldStateAccount( - final Address address, final Hash addressHash, final StateTrieAccountValue accountValue) { + final Address address, + final Hash addressHash, + final PmtStateTrieAccountValue accountValue) { this.address = address; this.addressHash = addressHash; @@ -454,8 +456,8 @@ public void commit() { private static Bytes serializeAccount( final long nonce, final Wei balance, final Hash storageRoot, final Hash codeHash) { - final StateTrieAccountValue accountValue = - new StateTrieAccountValue(nonce, balance, storageRoot, codeHash); + final PmtStateTrieAccountValue accountValue = + new PmtStateTrieAccountValue(nonce, balance, storageRoot, codeHash); return RLP.encode(accountValue::writeTo); } } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TrieGenerator.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TrieGenerator.java index 9a9108aa042..3e416a2879d 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TrieGenerator.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TrieGenerator.java @@ -20,9 +20,9 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.MerkleTrie; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; @@ -74,8 +74,9 @@ public static MerkleTrie generateTrie( }); final Bytes code = Bytes32.leftPad(Bytes.of(i + 10)); final Hash codeHash = Hash.hash(code); - final StateTrieAccountValue accountValue = - new StateTrieAccountValue(1L, Wei.of(2L), Hash.wrap(storageTrie.getRootHash()), codeHash); + final PmtStateTrieAccountValue accountValue = + new PmtStateTrieAccountValue( + 1L, Wei.of(2L), Hash.wrap(storageTrie.getRootHash()), codeHash); accountStateTrie.put(accounts.get(i), RLP.encode(accountValue::writeTo)); applyForStrategy( updater, diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/proof/WorldStateProofProviderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/proof/WorldStateProofProviderTest.java index 95b39197ea0..f7085e31e96 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/proof/WorldStateProofProviderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/proof/WorldStateProofProviderTest.java @@ -21,9 +21,9 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.MerkleTrie; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; @@ -82,8 +82,9 @@ public void getProofWhenWorldStateAvailable() { // Define account value final Hash codeHash = Hash.hash(Bytes.fromHexString("0x1122")); - final StateTrieAccountValue accountValue = - new StateTrieAccountValue(1L, Wei.of(2L), Hash.wrap(storageTrie.getRootHash()), codeHash); + final PmtStateTrieAccountValue accountValue = + new PmtStateTrieAccountValue( + 1L, Wei.of(2L), Hash.wrap(storageTrie.getRootHash()), codeHash); // Save to storage worldStateTrie.put(addressHash, RLP.encode(accountValue::writeTo)); worldStateTrie.commit((location, hash, value) -> updater.putAccountStateTrieNode(hash, value)); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiCachedMerkleTrieLoaderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiCachedMerkleTrieLoaderTest.java index 06b377ad83a..1552c341f33 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiCachedMerkleTrieLoaderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiCachedMerkleTrieLoaderTest.java @@ -25,11 +25,11 @@ import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.TrieIterator; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoader; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -96,8 +96,8 @@ void shouldAddAccountNodesInCacheDuringPreload() { @Test void shouldAddStorageNodesInCacheDuringPreload() { final Hash hashAccountZero = accounts.get(0).addressHash(); - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(trie.get(hashAccountZero).orElseThrow())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom(RLP.input(trie.get(hashAccountZero).orElseThrow())); final StoredMerklePatriciaTrie storageTrie = new StoredMerklePatriciaTrie<>( (location, hash) -> @@ -154,8 +154,8 @@ void shouldFallbackWhenAccountNodesIsNotInCache() { @Test void shouldFallbackWhenStorageNodesIsNotInCache() { final Hash hashAccountZero = accounts.get(0).addressHash(); - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(trie.get(hashAccountZero).orElseThrow())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom(RLP.input(trie.get(hashAccountZero).orElseThrow())); final StoredMerklePatriciaTrie storageTrie = new StoredMerklePatriciaTrie<>( (location, hash) -> diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorageTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorageTest.java index 464f35bae71..81e158bef76 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorageTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorageTest.java @@ -36,12 +36,12 @@ import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.StorageEntriesCollector; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.ImmutableDiffBasedSubStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -316,8 +316,8 @@ void getStorage_loadFromTrieWhenEmptyWithPartialMode(final FlatDbMode flatDbMode (TreeMap) trie.entriesFrom(root -> StorageEntriesCollector.collectEntries(root, Hash.ZERO, 1)); - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(accounts.firstEntry().getValue())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom(RLP.input(accounts.firstEntry().getValue())); final StoredMerklePatriciaTrie storageTrie = new StoredMerklePatriciaTrie<>( diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogFactoryTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogFactoryTests.java index 5173df717fc..ae685f0d009 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogFactoryTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogFactoryTests.java @@ -23,8 +23,8 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogLayer; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.plugin.services.trielogs.TrieLog; import org.hyperledger.besu.plugin.services.trielogs.TrieLogFactory; @@ -54,7 +54,7 @@ public class TrieLogFactoryTests { .addAccountChange( accountFixture, null, - new StateTrieAccountValue(0, Wei.fromEth(1), Hash.EMPTY, Hash.EMPTY)) + new PmtStateTrieAccountValue(0, Wei.fromEth(1), Hash.EMPTY, Hash.EMPTY)) .addCodeChange( Address.ZERO, null, diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogLayerTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogLayerTests.java index 85534de1b06..0aa00160fdb 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogLayerTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogLayerTests.java @@ -19,7 +19,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.StorageSlotKey; import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import java.util.Optional; @@ -51,15 +51,16 @@ public void testStorageSlotKeyEquivalence() { @Test public void testAddAccountChange() { Address address = Address.fromHexString("0x00"); - StateTrieAccountValue oldValue = new StateTrieAccountValue(0, Wei.ZERO, Hash.EMPTY, Hash.EMPTY); - StateTrieAccountValue newValue = - new StateTrieAccountValue(1, Wei.fromEth(1), Hash.EMPTY, Hash.EMPTY); + PmtStateTrieAccountValue oldValue = + new PmtStateTrieAccountValue(0, Wei.ZERO, Hash.EMPTY, Hash.EMPTY); + PmtStateTrieAccountValue newValue = + new PmtStateTrieAccountValue(1, Wei.fromEth(1), Hash.EMPTY, Hash.EMPTY); Address otherAddress = Address.fromHexString("0x000000"); - StateTrieAccountValue otherOldValue = - new StateTrieAccountValue(0, Wei.ZERO, Hash.EMPTY, Hash.EMPTY); - StateTrieAccountValue otherNewValue = - new StateTrieAccountValue(1, Wei.fromEth(1), Hash.EMPTY, Hash.EMPTY); + PmtStateTrieAccountValue otherOldValue = + new PmtStateTrieAccountValue(0, Wei.ZERO, Hash.EMPTY, Hash.EMPTY); + PmtStateTrieAccountValue otherNewValue = + new PmtStateTrieAccountValue(1, Wei.fromEth(1), Hash.EMPTY, Hash.EMPTY); trieLogLayer.addAccountChange(address, oldValue, newValue); otherTrieLogLayer.addAccountChange(otherAddress, otherOldValue, otherNewValue); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/worldstate/StateTrieAccountValueTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/worldstate/StateTrieAccountValueTest.java index 5ce385570c3..827900ef0c1 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/worldstate/StateTrieAccountValueTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/worldstate/StateTrieAccountValueTest.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPInput; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Test; @@ -41,11 +42,11 @@ public void roundTripMainNetAccountValue() { private void roundTripMainNetAccountValue( final long nonce, final Wei balance, final Hash storageRoot, final Hash codeHash) { - StateTrieAccountValue accountValue = - new StateTrieAccountValue(nonce, balance, storageRoot, codeHash); + PmtStateTrieAccountValue accountValue = + new PmtStateTrieAccountValue(nonce, balance, storageRoot, codeHash); Bytes encoded = RLP.encode(accountValue::writeTo); final RLPInput in = RLP.input(encoded); - StateTrieAccountValue roundTripAccountValue = StateTrieAccountValue.readFrom(in); + PmtStateTrieAccountValue roundTripAccountValue = PmtStateTrieAccountValue.readFrom(in); assertThat(nonce).isEqualTo(roundTripAccountValue.getNonce()); assertThat(balance).isEqualTo(roundTripAccountValue.getBalance()); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java index 899e7027243..a4c7dd1bf6f 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java @@ -85,7 +85,6 @@ protected boolean removeEldestEntry(final Map.Entry eldest) { private Optional checkpointHeader = Optional.empty(); - private final String protocolName; private final int maxMessageSize; private final Clock clock; private final List permissioningProviders; @@ -124,7 +123,6 @@ protected boolean removeEldestEntry(final Map.Entry eldest) { @VisibleForTesting public EthPeer( final PeerConnection connection, - final String protocolName, final Consumer onStatusesExchanged, final List peerValidators, final int maxMessageSize, @@ -132,7 +130,6 @@ public EthPeer( final List permissioningProviders, final Bytes localNodeId) { this.connection = connection; - this.protocolName = protocolName; this.maxMessageSize = maxMessageSize; this.clock = clock; this.permissioningProviders = permissioningProviders; @@ -153,21 +150,23 @@ private void initEthRequestManagers() { getAgreedCapabilities().stream().anyMatch(EthProtocol::isEth66Compatible); // eth protocol requestManagers.put( - protocolName, + EthProtocol.NAME, Map.ofEntries( Map.entry( EthPV62.GET_BLOCK_HEADERS, - new RequestManager(this, supportsRequestId, protocolName)), + new RequestManager(this, supportsRequestId, EthProtocol.NAME)), Map.entry( EthPV62.GET_BLOCK_BODIES, - new RequestManager(this, supportsRequestId, protocolName)), + new RequestManager(this, supportsRequestId, EthProtocol.NAME)), Map.entry( - EthPV63.GET_RECEIPTS, new RequestManager(this, supportsRequestId, protocolName)), + EthPV63.GET_RECEIPTS, + new RequestManager(this, supportsRequestId, EthProtocol.NAME)), Map.entry( - EthPV63.GET_NODE_DATA, new RequestManager(this, supportsRequestId, protocolName)), + EthPV63.GET_NODE_DATA, + new RequestManager(this, supportsRequestId, EthProtocol.NAME)), Map.entry( EthPV65.GET_POOLED_TRANSACTIONS, - new RequestManager(this, supportsRequestId, protocolName)))); + new RequestManager(this, supportsRequestId, EthProtocol.NAME)))); } private void initSnapRequestManagers() { @@ -237,7 +236,7 @@ public void disconnect(final DisconnectReason reason) { } public RequestManager.ResponseStream send(final MessageData messageData) throws PeerNotConnected { - return send(messageData, this.protocolName); + return send(messageData, EthProtocol.NAME); } public RequestManager.ResponseStream send( @@ -317,7 +316,7 @@ public RequestManager.ResponseStream getHeadersByHash( final GetBlockHeadersMessage message = GetBlockHeadersMessage.create(hash, maxHeaders, skip, reverse); final RequestManager requestManager = - requestManagers.get(protocolName).get(EthPV62.GET_BLOCK_HEADERS); + requestManagers.get(EthProtocol.NAME).get(EthPV62.GET_BLOCK_HEADERS); return sendRequest(requestManager, message); } @@ -326,32 +325,34 @@ public RequestManager.ResponseStream getHeadersByNumber( throws PeerNotConnected { final GetBlockHeadersMessage message = GetBlockHeadersMessage.create(blockNumber, maxHeaders, skip, reverse); - return sendRequest(requestManagers.get(protocolName).get(EthPV62.GET_BLOCK_HEADERS), message); + return sendRequest( + requestManagers.get(EthProtocol.NAME).get(EthPV62.GET_BLOCK_HEADERS), message); } public RequestManager.ResponseStream getBodies(final List blockHashes) throws PeerNotConnected { final GetBlockBodiesMessage message = GetBlockBodiesMessage.create(blockHashes); - return sendRequest(requestManagers.get(protocolName).get(EthPV62.GET_BLOCK_BODIES), message); + return sendRequest( + requestManagers.get(EthProtocol.NAME).get(EthPV62.GET_BLOCK_BODIES), message); } public RequestManager.ResponseStream getReceipts(final List blockHashes) throws PeerNotConnected { final GetReceiptsMessage message = GetReceiptsMessage.create(blockHashes); - return sendRequest(requestManagers.get(protocolName).get(EthPV63.GET_RECEIPTS), message); + return sendRequest(requestManagers.get(EthProtocol.NAME).get(EthPV63.GET_RECEIPTS), message); } public RequestManager.ResponseStream getNodeData(final Iterable nodeHashes) throws PeerNotConnected { final GetNodeDataMessage message = GetNodeDataMessage.create(nodeHashes); - return sendRequest(requestManagers.get(protocolName).get(EthPV63.GET_NODE_DATA), message); + return sendRequest(requestManagers.get(EthProtocol.NAME).get(EthPV63.GET_NODE_DATA), message); } public RequestManager.ResponseStream getPooledTransactions(final List hashes) throws PeerNotConnected { final GetPooledTransactionsMessage message = GetPooledTransactionsMessage.create(hashes); return sendRequest( - requestManagers.get(protocolName).get(EthPV65.GET_POOLED_TRANSACTIONS), message); + requestManagers.get(EthProtocol.NAME).get(EthPV65.GET_POOLED_TRANSACTIONS), message); } public RequestManager.ResponseStream getSnapAccountRange( @@ -461,7 +462,7 @@ Optional dispatch(final EthMessage ethMessage, final String prot * @param ethMessage the Eth message to dispatch */ void dispatch(final EthMessage ethMessage) { - dispatch(ethMessage, protocolName); + dispatch(ethMessage, EthProtocol.NAME); } /** @@ -587,10 +588,6 @@ public int getLastProtocolVersion() { return lastProtocolVersion.get(); } - public String getProtocolName() { - return protocolName; - } - /** * Return A read-only snapshot of this peer's current {@code chainState} * diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java index d19c7dfca2e..fda8bb0f167 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.eth.manager; import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.eth.EthProtocol; import org.hyperledger.besu.ethereum.eth.SnapProtocol; import org.hyperledger.besu.ethereum.eth.manager.EthPeer.DisconnectCallback; import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerSelector; @@ -92,7 +93,6 @@ public class EthPeers implements PeerSelector { .concurrencyLevel(1) .removalListener(this::onCacheRemoval) .build(); - private final String protocolName; private final Clock clock; private final List permissioningProviders; private final int maxMessageSize; @@ -122,7 +122,6 @@ public class EthPeers implements PeerSelector { () -> TrailingPeerRequirements.UNRESTRICTED; public EthPeers( - final String protocolName, final Supplier currentProtocolSpecSupplier, final Clock clock, final MetricsSystem metricsSystem, @@ -134,7 +133,6 @@ public EthPeers( final Boolean randomPeerPriority, final SyncMode syncMode, final ForkIdManager forkIdManager) { - this.protocolName = protocolName; this.currentProtocolSpecSupplier = currentProtocolSpecSupplier; this.clock = clock; this.permissioningProviders = permissioningProviders; @@ -191,7 +189,6 @@ public void registerNewConnection( peerInList.orElse( new EthPeer( newConnection, - protocolName, this::ethPeerStatusExchanged, peerValidators, maxMessageSize, @@ -294,7 +291,7 @@ public void dispatchMessage( } public void dispatchMessage(final EthPeer peer, final EthMessage ethMessage) { - dispatchMessage(peer, ethMessage, protocolName); + dispatchMessage(peer, ethMessage, EthProtocol.NAME); } @VisibleForTesting diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/task/GetReceiptsFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/task/GetReceiptsFromPeerTask.java index 7d4b5d585e5..b4b018b173c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/task/GetReceiptsFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/task/GetReceiptsFromPeerTask.java @@ -123,9 +123,8 @@ public Map> processResponse(final MessageD @Override public Predicate getPeerRequirementFilter() { return (ethPeer) -> - ethPeer.getProtocolName().equals(getSubProtocol().getName()) - && (protocolSchedule.anyMatch((ps) -> ps.spec().isPoS()) - || ethPeer.chainState().getEstimatedHeight() >= requiredBlockchainHeight); + (protocolSchedule.anyMatch((ps) -> ps.spec().isPoS()) + || ethPeer.chainState().getEstimatedHeight() >= requiredBlockchainHeight); } @Override diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessage.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessage.java index 71d04295925..9c6e1f93997 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessage.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessage.java @@ -20,7 +20,7 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLPInput; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import java.math.BigInteger; import java.util.List; @@ -121,7 +121,7 @@ public AccountRangeData accountData(final boolean withRequestId) { @VisibleForTesting public static Bytes toFullAccount(final RLPInput rlpInput) { - final StateTrieAccountValue accountValue = StateTrieAccountValue.readFrom(rlpInput); + final PmtStateTrieAccountValue accountValue = PmtStateTrieAccountValue.readFrom(rlpInput); final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); rlpOutput.startList(); @@ -135,7 +135,7 @@ public static Bytes toFullAccount(final RLPInput rlpInput) { } public static Bytes toSlimAccount(final RLPInput rlpInput) { - StateTrieAccountValue accountValue = StateTrieAccountValue.readFrom(rlpInput); + PmtStateTrieAccountValue accountValue = PmtStateTrieAccountValue.readFrom(rlpInput); var rlpOutput = new BytesValueRLPOutput(); rlpOutput.startList(); rlpOutput.writeLongScalar(accountValue.getNonce()); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DownloadHeadersStep.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DownloadHeadersStep.java index 6e404305823..ae568491587 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DownloadHeadersStep.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DownloadHeadersStep.java @@ -99,7 +99,6 @@ private CompletableFuture> downloadHeaders(final SyncTargetRan range.getStart().getNumber(), headerRequestSize, metricsSystem) - .assignPeer(range.getSyncTarget()) .run() .thenApply(PeerTaskResult::getResult); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/AccountTrieNodeDataRequest.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/AccountTrieNodeDataRequest.java index 366cfd50f51..28ac75e52f7 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/AccountTrieNodeDataRequest.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/AccountTrieNodeDataRequest.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.ethereum.rlp.RLPOutput; import org.hyperledger.besu.ethereum.trie.CompactEncoding; import org.hyperledger.besu.ethereum.trie.MerkleTrie; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; @@ -73,7 +73,8 @@ protected Stream getRequestsFromTrieNodeValue( final Bytes path, final Bytes value) { final Stream.Builder builder = Stream.builder(); - final StateTrieAccountValue accountValue = StateTrieAccountValue.readFrom(RLP.input(value)); + final PmtStateTrieAccountValue accountValue = + PmtStateTrieAccountValue.readFrom(RLP.input(value)); final Optional accountHash = Optional.of( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/AccountRangeDataRequest.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/AccountRangeDataRequest.java index 21a707e9a63..c7e76edc3f3 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/AccountRangeDataRequest.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/AccountRangeDataRequest.java @@ -31,9 +31,9 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.trie.NodeUpdater; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; @@ -210,8 +210,8 @@ public Stream getChildRequests( // find missing storages and code for (Map.Entry account : taskElement.keys().entrySet()) { - final StateTrieAccountValue accountValue = - StateTrieAccountValue.readFrom(RLP.input(account.getValue())); + final PmtStateTrieAccountValue accountValue = + PmtStateTrieAccountValue.readFrom(RLP.input(account.getValue())); if (!accountValue.getStorageRoot().equals(Hash.EMPTY_TRIE_HASH)) { childRequests.add( createStorageRangeDataRequest( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/AccountFlatDatabaseHealingRangeRequest.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/AccountFlatDatabaseHealingRangeRequest.java index 7e66fa7d88a..195cd85a576 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/AccountFlatDatabaseHealingRangeRequest.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/AccountFlatDatabaseHealingRangeRequest.java @@ -31,9 +31,9 @@ import org.hyperledger.besu.ethereum.trie.RangeManager; import org.hyperledger.besu.ethereum.trie.RangeStorageEntriesCollector; import org.hyperledger.besu.ethereum.trie.TrieIterator; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; @@ -104,8 +104,8 @@ public Stream getChildRequests( if (downloadState .getAccountsHealingList() .contains(CompactEncoding.bytesToPath(account.getKey()))) { - final StateTrieAccountValue accountValue = - StateTrieAccountValue.readFrom(RLP.input(account.getValue())); + final PmtStateTrieAccountValue accountValue = + PmtStateTrieAccountValue.readFrom(RLP.input(account.getValue())); childRequests.add( createStorageFlatHealingRangeRequest( getRootHash(), diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/AccountTrieNodeHealingRequest.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/AccountTrieNodeHealingRequest.java index be6060d52ef..70929f7dd93 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/AccountTrieNodeHealingRequest.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/AccountTrieNodeHealingRequest.java @@ -25,8 +25,8 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.CompactEncoding; import org.hyperledger.besu.ethereum.trie.MerkleTrie; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; @@ -120,7 +120,7 @@ public Stream getRootStorageRequests( getLocation().size(), account.size() - getLocation().size())) .map(RLP::input) - .map(StateTrieAccountValue::readFrom) + .map(PmtStateTrieAccountValue::readFrom) .filter( stateTrieAccountValue -> // We need to ensure that the accounts to be healed do not have empty storage. @@ -152,7 +152,8 @@ protected Stream getRequestsFromTrieNodeValue( final Bytes path, final Bytes value) { final Stream.Builder builder = Stream.builder(); - final StateTrieAccountValue accountValue = StateTrieAccountValue.readFrom(RLP.input(value)); + final PmtStateTrieAccountValue accountValue = + PmtStateTrieAccountValue.readFrom(RLP.input(value)); // Retrieve account hash final Hash accountHash = diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthPeerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthPeerTest.java index 99de00e6003..b5495e7636f 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthPeerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthPeerTest.java @@ -477,7 +477,6 @@ private EthPeer createPeerWithPeerInfo(final Bytes nodeId) { final Consumer onPeerReady = (peer) -> {}; return new EthPeer( peerConnection, - "foo", onPeerReady, Collections.emptyList(), EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE, @@ -513,7 +512,6 @@ private EthPeer createPeer( // that extend the sub-protocol work correctly return new EthPeer( peerConnection, - "foo", onPeerReady, peerValidators, EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestUtil.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestUtil.java index 0b0bd1e3eb7..3415a897a2d 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestUtil.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestUtil.java @@ -84,7 +84,6 @@ public static EthProtocolManager create( final EthPeers peers = new EthPeers( - EthProtocol.NAME, () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), TestClock.fixed(), new NoOpMetricsSystem(), @@ -211,7 +210,6 @@ public static EthProtocolManager create( final EthPeers peers = new EthPeers( - EthProtocol.NAME, () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), TestClock.fixed(), new NoOpMetricsSystem(), @@ -262,7 +260,6 @@ public static EthProtocolManager create( final EthPeers peers = new EthPeers( - EthProtocol.NAME, () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), TestClock.fixed(), new NoOpMetricsSystem(), @@ -294,7 +291,6 @@ public static EthProtocolManager create( final EthScheduler ethScheduler) { final EthPeers ethPeers = new EthPeers( - EthProtocol.NAME, () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), TestClock.fixed(), new NoOpMetricsSystem(), diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/RequestManagerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/RequestManagerTest.java index a00a08a7378..292aef78420 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/RequestManagerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/RequestManagerTest.java @@ -303,7 +303,6 @@ private EthPeer createPeer() { final Consumer onPeerReady = (peer) -> {}; return new EthPeer( peerConnection, - EthProtocol.NAME, onPeerReady, Collections.emptyList(), EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java index b1691d0af54..7de95304be6 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java @@ -27,7 +27,6 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.ethereum.core.MiningConfiguration; -import org.hyperledger.besu.ethereum.eth.EthProtocol; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthMessages; @@ -114,7 +113,6 @@ public void setupTest() { ethPeers = spy( new EthPeers( - EthProtocol.NAME, () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), TestClock.fixed(), metricsSystem, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/PeerMessageTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/PeerMessageTaskTest.java index 0ed6569387b..3def10fb8c9 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/PeerMessageTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/PeerMessageTaskTest.java @@ -162,7 +162,6 @@ protected EthPeer createPeer() { final Consumer onPeerReady = (peer) -> {}; return new EthPeer( peerConnection, - EthProtocol.NAME, onPeerReady, Collections.emptyList(), EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/task/GetReceiptsFromPeerTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/task/GetReceiptsFromPeerTaskTest.java index 90e6f738fcd..243db8462b3 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/task/GetReceiptsFromPeerTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/task/GetReceiptsFromPeerTaskTest.java @@ -214,11 +214,9 @@ public void testGetPeerRequirementFilter() { new GetReceiptsFromPeerTask( List.of(blockHeader1, blockHeader2, blockHeader3), protocolSchedule); - EthPeer failForIncorrectProtocol = mockPeer("incorrectProtocol", 5); - EthPeer failForShortChainHeight = mockPeer("incorrectProtocol", 1); - EthPeer successfulCandidate = mockPeer(EthProtocol.NAME, 5); + EthPeer failForShortChainHeight = mockPeer(1); + EthPeer successfulCandidate = mockPeer(5); - Assertions.assertFalse(task.getPeerRequirementFilter().test(failForIncorrectProtocol)); Assertions.assertFalse(task.getPeerRequirementFilter().test(failForShortChainHeight)); Assertions.assertTrue(task.getPeerRequirementFilter().test(successfulCandidate)); } @@ -251,11 +249,10 @@ private BlockHeader mockBlockHeader(final long blockNumber) { return blockHeader; } - private EthPeer mockPeer(final String protocol, final long chainHeight) { + private EthPeer mockPeer(final long chainHeight) { EthPeer ethPeer = Mockito.mock(EthPeer.class); ChainState chainState = Mockito.mock(ChainState.class); - Mockito.when(ethPeer.getProtocolName()).thenReturn(protocol); Mockito.when(ethPeer.chainState()).thenReturn(chainState); Mockito.when(chainState.getEstimatedHeight()).thenReturn(chainHeight); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java index 28446034296..1d43a5af9b9 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java @@ -37,13 +37,13 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.CompactEncoding; import org.hyperledger.besu.ethereum.trie.MerkleTrie; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFlatDbStrategyProvider; import org.hyperledger.besu.ethereum.trie.patricia.SimpleMerklePatriciaTrie; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.ObservableMetricsSystem; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -71,7 +71,7 @@ public class SnapServerTest { record SnapTestAccount( Hash addressHash, - StateTrieAccountValue accountValue, + PmtStateTrieAccountValue accountValue, MerkleTrie storage, Bytes code) { Bytes accountRLP() { @@ -722,7 +722,7 @@ public void assertCodeLimitRequest_atLeastOneByteCode() { static SnapTestAccount createTestAccount(final String hexAddr) { return new SnapTestAccount( Hash.wrap(Bytes32.rightPad(Bytes.fromHexString(hexAddr))), - new StateTrieAccountValue( + new PmtStateTrieAccountValue( rand.nextInt(0, 1), Wei.of(rand.nextLong(0L, 1L)), Hash.EMPTY_TRIE_HASH, Hash.EMPTY), new SimpleMerklePatriciaTrie<>(a -> a), Bytes.EMPTY); @@ -768,7 +768,7 @@ static SnapTestAccount createTestContractAccount( updater.commit(); return new SnapTestAccount( acctHash, - new StateTrieAccountValue( + new PmtStateTrieAccountValue( rand.nextInt(0, 1), Wei.of(rand.nextLong(0L, 1L)), Hash.wrap(trie.getRootHash()), Hash.hash(mockCode)), trie, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessageTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessageTest.java index c7e5bf74c42..4c2bad0f639 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessageTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessageTest.java @@ -23,7 +23,7 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPInput; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import java.util.ArrayList; import java.util.HashMap; @@ -39,8 +39,8 @@ public final class AccountRangeMessageTest { @Test public void roundTripTest() { final Map keys = new HashMap<>(); - final StateTrieAccountValue accountValue = - new StateTrieAccountValue(1L, Wei.of(2L), Hash.EMPTY_TRIE_HASH, Hash.EMPTY); + final PmtStateTrieAccountValue accountValue = + new PmtStateTrieAccountValue(1L, Wei.of(2L), Hash.EMPTY_TRIE_HASH, Hash.EMPTY); keys.put(Hash.wrap(Bytes32.leftPad(Bytes.of(1))), RLP.encode(accountValue::writeTo)); final List proofs = new ArrayList<>(); @@ -65,8 +65,8 @@ public void toSlimAccountTest() { Wei balance = Wei.of(2L); // Create a StateTrieAccountValue with the given nonce and balance - final StateTrieAccountValue accountValue = - new StateTrieAccountValue(nonce, balance, Hash.EMPTY_TRIE_HASH, Hash.EMPTY); + final PmtStateTrieAccountValue accountValue = + new PmtStateTrieAccountValue(nonce, balance, Hash.EMPTY_TRIE_HASH, Hash.EMPTY); // Encode the account value to RLP final BytesValueRLPOutput rlpOut = new BytesValueRLPOutput(); @@ -104,8 +104,8 @@ public void toFullAccountTest() { Wei balance = Wei.of(2L); // Create a StateTrieAccountValue with the given nonce and balance - final StateTrieAccountValue accountValue = - new StateTrieAccountValue(nonce, balance, Hash.EMPTY_TRIE_HASH, Hash.EMPTY); + final PmtStateTrieAccountValue accountValue = + new PmtStateTrieAccountValue(nonce, balance, Hash.EMPTY_TRIE_HASH, Hash.EMPTY); // Encode the account value to RLP final BytesValueRLPOutput rlpOut = new BytesValueRLPOutput(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java index c576b7f8e26..cae4c8ff85a 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java @@ -641,7 +641,6 @@ public void shouldNotImportBlocksThatAreAlreadyBeingImported() { final EthContext ethContext = new EthContext( new EthPeers( - "eth", () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), TestClock.fixed(), metricsSystem, @@ -783,7 +782,6 @@ public Object answer(final InvocationOnMock invocation) throws Throwable { final EthContext ethContext = new EthContext( new EthPeers( - "eth", () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), TestClock.fixed(), metricsSystem, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloaderTest.java index 75fe892aebd..323f0ae9f10 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloaderTest.java @@ -51,11 +51,11 @@ import org.hyperledger.besu.ethereum.storage.keyvalue.WorldStatePreimageKeyValueStorage; import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.Node; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.forest.ForestWorldStateArchive; import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.trie.patricia.TrieNodeDecoder; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage; @@ -589,8 +589,8 @@ void doesNotRequestKnownStorageTrieNodesFromNetwork() { Function.identity()) .entriesFrom(Bytes32.ZERO, 5).values().stream() .map(RLP::input) - .map(StateTrieAccountValue::readFrom) - .map(StateTrieAccountValue::getStorageRoot) + .map(PmtStateTrieAccountValue::readFrom) + .map(PmtStateTrieAccountValue::getStorageRoot) .collect(Collectors.toList()); final Map allTrieNodes = new HashMap<>(); final Set knownNodes = new HashSet<>(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/AccountHealingTrackingTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/AccountHealingTrackingTest.java index 8e4e40311f3..ecb704ba89e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/AccountHealingTrackingTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/AccountHealingTrackingTest.java @@ -31,11 +31,11 @@ import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.RangeStorageEntriesCollector; import org.hyperledger.besu.ethereum.trie.TrieIterator; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.trie.patricia.StoredNodeFactory; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -82,8 +82,9 @@ public void setup() { @Test void shouldMarkAccountForHealingWhenStorageProofIsReceived() { final Hash accountHash = Hash.hash(accounts.get(0)); - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom( + RLP.input(accountStateTrie.get(accountHash).orElseThrow())); final StoredMerklePatriciaTrie storageTrie = new StoredMerklePatriciaTrie<>( @@ -130,8 +131,9 @@ void shouldMarkAccountForHealingWhenStorageProofIsReceived() { @Test void shouldNotMarkAccountForHealingWhenAllStorageIsReceivedWithoutProof() { final Hash accountHash = Hash.hash(accounts.get(0)); - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom( + RLP.input(accountStateTrie.get(accountHash).orElseThrow())); final StoredMerklePatriciaTrie storageTrie = new StoredMerklePatriciaTrie<>( @@ -171,8 +173,9 @@ void shouldNotMarkAccountForHealingWhenAllStorageIsReceivedWithoutProof() { @Test void shouldMarkAccountForHealingOnInvalidStorageProof() { final Hash accountHash = Hash.hash(accounts.get(0)); - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom( + RLP.input(accountStateTrie.get(accountHash).orElseThrow())); final List proofs = List.of( @@ -197,8 +200,9 @@ void shouldMarkAccountForHealingOnInvalidStorageProof() { @Test void shouldMarkAccountForHealingOnInvalidStorageWithoutProof() { final Hash accountHash = Hash.hash(accounts.get(0)); - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom( + RLP.input(accountStateTrie.get(accountHash).orElseThrow())); final StoredMerklePatriciaTrie storageTrie = new StoredMerklePatriciaTrie<>( @@ -236,8 +240,9 @@ void shouldMarkAccountForHealingOnInvalidStorageWithoutProof() { @Test void shouldMarkAccountForHealingOnPartialStorageRange() { final Hash accountHash = Hash.hash(accounts.get(0)); - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom( + RLP.input(accountStateTrie.get(accountHash).orElseThrow())); final StoredMerklePatriciaTrie storageTrie = new StoredMerklePatriciaTrie<>( @@ -286,8 +291,9 @@ void shouldMarkAccountForHealingOnPartialStorageRange() { @Test void shouldNotMarkAccountForHealingOnValidStorageTrieNodeDetection() { final Hash accountHash = Hash.hash(accounts.get(0)); - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom( + RLP.input(accountStateTrie.get(accountHash).orElseThrow())); final StorageTrieNodeHealingRequest storageTrieNodeHealingRequest = SnapDataRequest.createStorageTrieNodeDataRequest( stateTrieAccountValue.getStorageRoot(), diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/TaskGenerator.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/TaskGenerator.java index 0b3a17cccff..2031e7a2a7b 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/TaskGenerator.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/TaskGenerator.java @@ -27,10 +27,10 @@ import org.hyperledger.besu.ethereum.trie.RangeManager; import org.hyperledger.besu.ethereum.trie.RangeStorageEntriesCollector; import org.hyperledger.besu.ethereum.trie.TrieIterator; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.services.tasks.Task; @@ -81,8 +81,8 @@ public static List> createAccountRequest( accountRangeDataRequest.addResponse(worldStateProofProvider, accounts, new ArrayDeque<>()); } - final StateTrieAccountValue stateTrieAccountValue = - StateTrieAccountValue.readFrom(RLP.input(accounts.firstEntry().getValue())); + final PmtStateTrieAccountValue stateTrieAccountValue = + PmtStateTrieAccountValue.readFrom(RLP.input(accounts.firstEntry().getValue())); final Hash accountHash = Hash.wrap(accounts.firstKey()); final StorageRangeDataRequest storageRangeDataRequest = diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageFlatDatabaseHealingRangeRequestTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageFlatDatabaseHealingRangeRequestTest.java index fb8dd742857..5eb88521ae9 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageFlatDatabaseHealingRangeRequestTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageFlatDatabaseHealingRangeRequestTest.java @@ -31,10 +31,10 @@ import org.hyperledger.besu.ethereum.trie.RangeManager; import org.hyperledger.besu.ethereum.trie.RangeStorageEntriesCollector; import org.hyperledger.besu.ethereum.trie.TrieIterator; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -97,8 +97,8 @@ public void setup() { account0StorageRoot = trie.get(account0Hash) .map(RLP::input) - .map(StateTrieAccountValue::readFrom) - .map(StateTrieAccountValue::getStorageRoot) + .map(PmtStateTrieAccountValue::readFrom) + .map(PmtStateTrieAccountValue::getStorageRoot) .orElseThrow(); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageTrieNodeHealingRequestTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageTrieNodeHealingRequestTest.java index 4f8299f9acd..114399a66a1 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageTrieNodeHealingRequestTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageTrieNodeHealingRequestTest.java @@ -23,10 +23,10 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.trie.MerkleTrie; +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -92,8 +92,8 @@ public void setup(final DataStorageFormat storageFormat) { account0StorageRoot = trie.get(account0Hash) .map(RLP::input) - .map(StateTrieAccountValue::readFrom) - .map(StateTrieAccountValue::getStorageRoot) + .map(PmtStateTrieAccountValue::readFrom) + .map(PmtStateTrieAccountValue::getStorageRoot) .orElseThrow(); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java index d042996ce7a..ce3443eaa9d 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java @@ -154,7 +154,6 @@ public boolean isMessagePermitted(final EnodeURL destinationEnode, final int cod }; final EthPeers ethPeers = new EthPeers( - EthProtocol.NAME, () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), TestClock.fixed(), metricsSystem, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java index 612a1de9dfb..11b0f59f690 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java @@ -112,7 +112,6 @@ public void setup() { final NodeMessagePermissioningProvider nmpp = (destinationEnode, code) -> true; ethPeers = new EthPeers( - "ETH", () -> protocolSpec, TestClock.fixed(), new NoOpMetricsSystem(), diff --git a/ethereum/permissioning/src/main/java/org/hyperledger/besu/ethereum/permissioning/NodeLocalConfigPermissioningController.java b/ethereum/permissioning/src/main/java/org/hyperledger/besu/ethereum/permissioning/NodeLocalConfigPermissioningController.java index ec66ea51eff..b5878d14de3 100644 --- a/ethereum/permissioning/src/main/java/org/hyperledger/besu/ethereum/permissioning/NodeLocalConfigPermissioningController.java +++ b/ethereum/permissioning/src/main/java/org/hyperledger/besu/ethereum/permissioning/NodeLocalConfigPermissioningController.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -48,7 +49,7 @@ public class NodeLocalConfigPermissioningController implements NodeConnectionPer private LocalPermissioningConfiguration configuration; private final List fixedNodes; private final Bytes localNodeId; - private final List nodesAllowlist = new ArrayList<>(); + private final List nodesAllowlist = new CopyOnWriteArrayList<>(); private final AllowlistPersistor allowlistPersistor; private final Subscribers> nodeAllowlistUpdatedObservers = Subscribers.create(); diff --git a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeLocalConfigPermissioningControllerTest.java b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeLocalConfigPermissioningControllerTest.java index 106f9c36100..5db372b63ac 100644 --- a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeLocalConfigPermissioningControllerTest.java +++ b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeLocalConfigPermissioningControllerTest.java @@ -46,6 +46,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import com.google.common.collect.Lists; @@ -316,6 +317,56 @@ public void whenCheckingIfNodeIsPermittedOrderDoesNotMatter() { .isTrue(); } + @Test + public void whenCallingIsPermittedAndRemovingEntryInAnotherThreadShouldNotThrowException() + throws InterruptedException { + // Add a node to the allowlist + controller.addNodes(Lists.newArrayList(enode1)); + + // Atomic flag to detect exceptions + AtomicBoolean exceptionOccurred = new AtomicBoolean(false); + + // Create a thread to call isPermitted + Thread isPermittedThread = + new Thread( + () -> { + try { + for (int i = 0; i < 1000; i++) { + controller.isPermitted(enode1); + } + } catch (Exception e) { + exceptionOccurred.set(true); + e.printStackTrace(); + } + }); + + // Create a thread to modify the allowlist + Thread modifyAllowlistThread = + new Thread( + () -> { + try { + for (int i = 0; i < 1000; i++) { + controller.removeNodes(Lists.newArrayList(enode1)); + controller.addNodes(Lists.newArrayList(enode1)); + } + } catch (Exception e) { + exceptionOccurred.set(true); + e.printStackTrace(); + } + }); + + // Start both threads + isPermittedThread.start(); + modifyAllowlistThread.start(); + + // Wait for both threads to complete + isPermittedThread.join(); + modifyAllowlistThread.join(); + + // Assert no exceptions were thrown + assert (!exceptionOccurred.get()); + } + @Test public void stateShouldRevertIfAllowlistPersistFails() throws IOException, AllowlistFileSyncException { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java index 9f065aee98b..f571ff2ff03 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java @@ -128,6 +128,7 @@ public A getWrappedAccount() { public void setWrappedAccount(final A account) { if (this.account == null) { this.account = account; + storageWasCleared = false; } else { throw new IllegalStateException("Already tracking a wrapped account"); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java index 4cbda732798..9b57b6ab9e3 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java @@ -24,8 +24,6 @@ import java.util.Collection; import java.util.Optional; -import org.apache.tuweni.bytes.Bytes; - /** * An object that buffers updates made over a particular {@link WorldView}. * @@ -75,29 +73,8 @@ default MutableAccount createAccount(final Address address) { * #createAccount(Address)} (and thus all his fields will be zero/empty). */ default MutableAccount getOrCreate(final Address address) { - MutableAccount account = getAccount(address); - if (account == null) { - account = createAccount(address); - if (parentUpdater().isPresent() && parentUpdater().get().isDeleted(address)) { - account.clearStorage(); - account.setCode(Bytes.EMPTY); - } - } - return account; - } - - /** - * Check this and parent updaters to see if an address has been deleted since the last persist - * - * @param address address to check - * @return true if any updaters have marked the address as deleted. - */ - default boolean isDeleted(final Address address) { - if (getDeletedAccountAddresses().contains(address)) { - return true; - } else { - return parentUpdater().map(wu -> wu.isDeleted(address)).orElse(false); - } + final MutableAccount account = getAccount(address); + return account == null ? createAccount(address) : account; } /** diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 5b2ca88318b..3437aaa139e 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -464,35 +464,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1924,14 +1895,6 @@ - - - - - - - - @@ -1945,11 +1908,6 @@ - - - - - @@ -1960,14 +1918,6 @@ - - - - - - - - @@ -1976,14 +1926,6 @@ - - - - - - - - @@ -1992,14 +1934,6 @@ - - - - - - - - @@ -2008,14 +1942,6 @@ - - - - - - - - @@ -2029,14 +1955,6 @@ - - - - - - - - @@ -2050,14 +1968,6 @@ - - - - - - - - @@ -2066,14 +1976,6 @@ - - - - - - - - @@ -2082,14 +1984,6 @@ - - - - - - - - @@ -2098,14 +1992,6 @@ - - - - - - - - @@ -2114,14 +2000,6 @@ - - - - - - - - @@ -2130,14 +2008,6 @@ - - - - - - - - @@ -2146,14 +2016,6 @@ - - - - - - - - @@ -2162,14 +2024,6 @@ - - - - - - - - @@ -2183,14 +2037,6 @@ - - - - - - - - @@ -2204,14 +2050,6 @@ - - - - - - - - @@ -2225,14 +2063,6 @@ - - - - - - - - @@ -2241,14 +2071,6 @@ - - - - - - - - @@ -2262,11 +2084,6 @@ - - - - - @@ -2277,14 +2094,6 @@ - - - - - - - - @@ -2298,14 +2107,6 @@ - - - - - - - - @@ -2314,14 +2115,6 @@ - - - - - - - - @@ -2330,17 +2123,6 @@ - - - - - - - - - - - @@ -2357,14 +2139,6 @@ - - - - - - - - @@ -2373,14 +2147,6 @@ - - - - - - - - @@ -2389,11 +2155,6 @@ - - - - - @@ -2404,14 +2165,6 @@ - - - - - - - - @@ -2420,14 +2173,6 @@ - - - - - - - - @@ -2436,14 +2181,6 @@ - - - - - - - - @@ -2457,23 +2194,6 @@ - - - - - - - - - - - - - - - - - @@ -2496,20 +2216,6 @@ - - - - - - - - - - - - - - @@ -2529,14 +2235,6 @@ - - - - - - - - @@ -2545,14 +2243,6 @@ - - - - - - - - @@ -2561,14 +2251,6 @@ - - - - - - - - @@ -2577,14 +2259,6 @@ - - - - - - - - @@ -2636,6 +2310,22 @@ + + + + + + + + + + + + + + + + @@ -2803,6 +2493,22 @@ + + + + + + + + + + + + + + + + @@ -2923,11 +2629,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2936,11 +2769,6 @@ - - - - - @@ -2949,22 +2777,6 @@ - - - - - - - - - - - - - - - - @@ -2973,14 +2785,6 @@ - - - - - - - - @@ -5628,14 +5432,6 @@ - - - - - - - - @@ -6160,14 +5956,6 @@ - - - - - - - - @@ -6577,20 +6365,12 @@ - - - + + + - - - - - - - - - - + + @@ -6725,14 +6505,6 @@ - - - - - - - - diff --git a/metrics/core/build.gradle b/metrics/core/build.gradle index 160093c7490..e10057d466f 100644 --- a/metrics/core/build.gradle +++ b/metrics/core/build.gradle @@ -55,11 +55,12 @@ dependencies { implementation 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure' implementation 'io.opentelemetry.semconv:opentelemetry-semconv' - implementation 'io.prometheus:simpleclient' - implementation 'io.prometheus:simpleclient_common' - implementation 'io.prometheus:simpleclient_guava' - implementation 'io.prometheus:simpleclient_hotspot' - implementation 'io.prometheus:simpleclient_pushgateway' + implementation 'io.prometheus:prometheus-metrics-core' + implementation 'io.prometheus:prometheus-metrics-instrumentation-guava' + implementation 'io.prometheus:prometheus-metrics-instrumentation-jvm' + implementation 'io.prometheus:prometheus-metrics-exporter-httpserver' + implementation 'io.prometheus:prometheus-metrics-exporter-pushgateway' + implementation 'io.vertx:vertx-core' implementation 'io.vertx:vertx-web' diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricsService.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricsService.java index 747ed9cc762..7eb37061503 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricsService.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricsService.java @@ -18,12 +18,12 @@ import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsHttpService; import org.hyperledger.besu.metrics.prometheus.MetricsPushGatewayService; +import org.hyperledger.besu.metrics.prometheus.PrometheusMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.Optional; import java.util.concurrent.CompletableFuture; -import io.vertx.core.Vertx; import org.slf4j.LoggerFactory; /** @@ -35,20 +35,18 @@ public interface MetricsService { /** * Create Metrics Service. * - * @param vertx the vertx * @param configuration the configuration * @param metricsSystem the metrics system * @return the optional Metrics Service */ static Optional create( - final Vertx vertx, - final MetricsConfiguration configuration, - final MetricsSystem metricsSystem) { + final MetricsConfiguration configuration, final MetricsSystem metricsSystem) { LoggerFactory.getLogger(MetricsService.class) .trace("Creating metrics service {}", configuration.getProtocol()); if (configuration.getProtocol() == MetricsProtocol.PROMETHEUS) { if (configuration.isEnabled()) { - return Optional.of(new MetricsHttpService(vertx, configuration, metricsSystem)); + return Optional.of( + new MetricsHttpService(configuration, (PrometheusMetricsSystem) metricsSystem)); } else if (configuration.isPushEnabled()) { return Optional.of(new MetricsPushGatewayService(configuration, metricsSystem)); } else { diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/Observation.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/Observation.java index 81ca8b5a75f..280eeef220c 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/Observation.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/Observation.java @@ -17,99 +17,14 @@ import org.hyperledger.besu.plugin.services.metrics.MetricCategory; import java.util.List; -import java.util.Objects; -import com.google.common.base.MoreObjects; - -/** The Observation. */ -public class Observation { - private final MetricCategory category; - private final String metricName; - private final List labels; - private final Object value; - - /** - * Instantiates a new Observation. - * - * @param category the category - * @param metricName the metric name - * @param value the value - * @param labels the labels - */ - public Observation( - final MetricCategory category, - final String metricName, - final Object value, - final List labels) { - this.category = category; - this.metricName = metricName; - this.value = value; - this.labels = labels; - } - - /** - * Gets category. - * - * @return the category - */ - public MetricCategory getCategory() { - return category; - } - - /** - * Gets metric name. - * - * @return the metric name - */ - public String getMetricName() { - return metricName; - } - - /** - * Gets labels. - * - * @return the labels - */ - public List getLabels() { - return labels; - } - - /** - * Gets value. - * - * @return the value - */ - public Object getValue() { - return value; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final Observation that = (Observation) o; - return Objects.equals(category, that.category) - && Objects.equals(metricName, that.metricName) - && Objects.equals(labels, that.labels) - && Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(category, metricName, labels, value); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("category", category) - .add("metricName", metricName) - .add("labels", labels) - .add("value", value) - .toString(); - } -} +/** + * The Observation. + * + * @param category the category + * @param metricName the metric name + * @param value the value + * @param labels the labels + */ +public record Observation( + MetricCategory category, String metricName, Object value, List labels) {} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpMetricsSystem.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpMetricsSystem.java index 59de732c7ae..a4c95cbb819 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpMetricsSystem.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpMetricsSystem.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.plugin.services.metrics.LabelledGauge; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedMetric; +import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedSummary; import org.hyperledger.besu.plugin.services.metrics.MetricCategory; import org.hyperledger.besu.plugin.services.metrics.OperationTimer; @@ -42,17 +43,11 @@ public class NoOpMetricsSystem implements ObservableMetricsSystem { /** The constant NO_OP_COUNTER. */ public static final Counter NO_OP_COUNTER = new NoOpCounter(); - /** The constant NO_OP_GAUGE. */ - public static final LabelledSuppliedMetric NO_OP_GAUGE = new NoOpValueCollector(); - private static final OperationTimer.TimingContext NO_OP_TIMING_CONTEXT = () -> 0; /** The constant NO_OP_OPERATION_TIMER. */ public static final OperationTimer NO_OP_OPERATION_TIMER = () -> NO_OP_TIMING_CONTEXT; - /** The constant NO_OP_HISTOGRAM. */ - public static final Histogram NO_OP_HISTOGRAM = d -> {}; - /** The constant NO_OP_LABELLED_1_COUNTER. */ public static final LabelledMetric NO_OP_LABELLED_1_COUNTER = new LabelCountingNoOpMetric<>(1, NO_OP_COUNTER); @@ -69,21 +64,8 @@ public class NoOpMetricsSystem implements ObservableMetricsSystem { public static final LabelledMetric NO_OP_LABELLED_1_OPERATION_TIMER = new LabelCountingNoOpMetric<>(1, NO_OP_OPERATION_TIMER); - /** The constant NO_OP_LABELLED_1_HISTOGRAM. */ - public static final LabelledMetric NO_OP_LABELLED_1_HISTOGRAM = - new LabelCountingNoOpMetric<>(1, NO_OP_HISTOGRAM); - - /** The constant NO_OP_LABELLED_1_GAUGE. */ - public static final LabelledSuppliedMetric NO_OP_LABELLED_1_GAUGE = - new LabelledSuppliedNoOpMetric(1, NO_OP_GAUGE); - - /** The constant NO_OP_LABELLED_2_GAUGE. */ - public static final LabelledSuppliedMetric NO_OP_LABELLED_2_GAUGE = - new LabelledSuppliedNoOpMetric(2, NO_OP_GAUGE); - - /** The constant NO_OP_LABELLED_3_GAUGE. */ - public static final LabelledSuppliedMetric NO_OP_LABELLED_3_GAUGE = - new LabelledSuppliedNoOpMetric(3, NO_OP_GAUGE); + /** The constant NO_OP_HISTOGRAM. */ + public static final Histogram NO_OP_HISTOGRAM = d -> {}; /** Default constructor */ public NoOpMetricsSystem() {} @@ -104,16 +86,7 @@ public LabelledMetric createLabelledCounter( * @return the counter labelled metric */ public static LabelledMetric getCounterLabelledMetric(final int labelCount) { - switch (labelCount) { - case 1: - return NO_OP_LABELLED_1_COUNTER; - case 2: - return NO_OP_LABELLED_2_COUNTER; - case 3: - return NO_OP_LABELLED_3_COUNTER; - default: - return new LabelCountingNoOpMetric<>(labelCount, NO_OP_COUNTER); - } + return new LabelCountingNoOpMetric<>(labelCount, NO_OP_COUNTER); } @Override @@ -126,11 +99,13 @@ public LabelledMetric createSimpleLabelledTimer( } @Override - public void trackExternalSummary( + public LabelledSuppliedSummary createLabelledSuppliedSummary( final MetricCategory category, final String name, final String help, - final Supplier summarySupplier) {} + final String... labelNames) { + return getLabelledSuppliedSummary(labelNames.length); + } @Override public LabelledMetric createLabelledTimer( @@ -149,25 +124,7 @@ public LabelledMetric createLabelledTimer( */ public static LabelledMetric getOperationTimerLabelledMetric( final int labelCount) { - if (labelCount == 1) { - return NO_OP_LABELLED_1_OPERATION_TIMER; - } else { - return new LabelCountingNoOpMetric<>(labelCount, NO_OP_OPERATION_TIMER); - } - } - - /** - * Gets histogram labelled metric. - * - * @param labelCount the label count - * @return the histogram labelled metric - */ - public static LabelledMetric getHistogramLabelledMetric(final int labelCount) { - if (labelCount == 1) { - return NO_OP_LABELLED_1_HISTOGRAM; - } else { - return new LabelCountingNoOpMetric<>(labelCount, NO_OP_HISTOGRAM); - } + return new LabelCountingNoOpMetric<>(labelCount, NO_OP_OPERATION_TIMER); } @Override @@ -177,10 +134,6 @@ public void createGauge( final String help, final DoubleSupplier valueSupplier) {} - @Override - public void createGuavaCacheCollector( - final MetricCategory category, final String name, final Cache cache) {} - @Override public LabelledMetric createLabelledHistogram( final MetricCategory category, @@ -188,9 +141,23 @@ public LabelledMetric createLabelledHistogram( final String help, final double[] buckets, final String... labelNames) { - return null; + return getHistogramLabelledMetric(labelNames.length); + } + + /** + * Gets histogram labelled metric. + * + * @param labelCount the label count + * @return the histogram labelled metric + */ + public static LabelledMetric getHistogramLabelledMetric(final int labelCount) { + return new LabelCountingNoOpMetric<>(labelCount, NO_OP_HISTOGRAM); } + @Override + public void createGuavaCacheCollector( + final MetricCategory category, final String name, final Cache cache) {} + @Override public LabelledSuppliedMetric createLabelledSuppliedCounter( final MetricCategory category, @@ -216,16 +183,17 @@ public LabelledSuppliedMetric createLabelledSuppliedGauge( * @return the labelled gauge */ public static LabelledSuppliedMetric getLabelledSuppliedMetric(final int labelCount) { - switch (labelCount) { - case 1: - return NO_OP_LABELLED_1_GAUGE; - case 2: - return NO_OP_LABELLED_2_GAUGE; - case 3: - return NO_OP_LABELLED_3_GAUGE; - default: - return new LabelledSuppliedNoOpMetric(labelCount, NO_OP_GAUGE); - } + return new LabelledSuppliedNoOpMetric(labelCount); + } + + /** + * Gets labelled supplied histogram. + * + * @param labelCount the label count + * @return the labelled gauge + */ + public static LabelledSuppliedSummary getLabelledSuppliedSummary(final int labelCount) { + return new LabelledSuppliedNoOpMetric(labelCount); } @Override @@ -281,7 +249,8 @@ public T labels(final String... labels) { /** The Labelled supplied NoOp metric. */ @SuppressWarnings("removal") // remove when deprecated LabelledGauge is removed - public static class LabelledSuppliedNoOpMetric implements LabelledSuppliedMetric, LabelledGauge { + public static class LabelledSuppliedNoOpMetric + implements LabelledSuppliedMetric, LabelledGauge, LabelledSuppliedSummary { /** The Label count. */ final int labelCount; @@ -289,22 +258,26 @@ public static class LabelledSuppliedNoOpMetric implements LabelledSuppliedMetric final List labelValuesCache = new ArrayList<>(); /** - * Instantiates a new Labelled gauge NoOp metric. + * Instantiates a new Labelled supplied NoOp metric. * * @param labelCount the label count - * @param fakeMetric the fake metric */ - public LabelledSuppliedNoOpMetric( - final int labelCount, final LabelledSuppliedMetric fakeMetric) { + public LabelledSuppliedNoOpMetric(final int labelCount) { this.labelCount = labelCount; - this.fakeMetric = fakeMetric; } - /** The Fake metric. */ - final LabelledSuppliedMetric fakeMetric; - @Override public void labels(final DoubleSupplier valueSupplier, final String... labelValues) { + internalLabels(valueSupplier, labelValues); + } + + @Override + public void labels( + final Supplier summarySupplier, final String... labelValues) { + internalLabels(summarySupplier, labelValues); + } + + private void internalLabels(final Object valueSupplier, final String... labelValues) { final String labelValuesString = String.join(",", labelValues); Preconditions.checkArgument( !labelValuesCache.contains(labelValuesString), @@ -313,6 +286,7 @@ public void labels(final DoubleSupplier valueSupplier, final String... labelValu labelValues.length == labelCount, "The count of labels used must match the count of labels expected."); Preconditions.checkNotNull(valueSupplier, "No valueSupplier specified"); + labelValuesCache.add(labelValuesString); } } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java index ae178edc977..33389828d3c 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java @@ -20,10 +20,10 @@ import org.hyperledger.besu.metrics.StandardMetricCategory; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; -import org.hyperledger.besu.plugin.services.metrics.ExternalSummary; import org.hyperledger.besu.plugin.services.metrics.Histogram; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedMetric; +import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedSummary; import org.hyperledger.besu.plugin.services.metrics.MetricCategory; import org.hyperledger.besu.plugin.services.metrics.OperationTimer; @@ -42,7 +42,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.function.DoubleSupplier; -import java.util.function.Supplier; import java.util.stream.Stream; import javax.inject.Singleton; @@ -135,7 +134,7 @@ public OpenTelemetrySystem( @Override public Stream streamObservations(final MetricCategory category) { - return streamObservations().filter(metricData -> metricData.getCategory().equals(category)); + return streamObservations().filter(metricData -> metricData.category().equals(category)); } @Override @@ -247,11 +246,14 @@ public LabelledMetric createSimpleLabelledTimer( } @Override - public void trackExternalSummary( + public LabelledSuppliedSummary createLabelledSuppliedSummary( final MetricCategory category, final String name, final String help, - final Supplier summarySupplier) {} + final String... labelNames) { + // not yet supported + return (LabelledSuppliedSummary) NoOpMetricsSystem.getLabelledSuppliedMetric(labelNames.length); + } @Override public LabelledMetric createLabelledTimer( @@ -288,10 +290,6 @@ public void createGauge( } } - @Override - public void createGuavaCacheCollector( - final MetricCategory category, final String name, final Cache cache) {} - @Override public LabelledMetric createLabelledHistogram( final MetricCategory category, @@ -299,9 +297,14 @@ public LabelledMetric createLabelledHistogram( final String help, final double[] buckets, final String... labelNames) { - return null; + // not yet supported + return NoOpMetricsSystem.getHistogramLabelledMetric(labelNames.length); } + @Override + public void createGuavaCacheCollector( + final MetricCategory category, final String name, final Cache cache) {} + @Override public LabelledSuppliedMetric createLabelledSuppliedCounter( final MetricCategory category, diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/AbstractPrometheusHistogram.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/AbstractPrometheusHistogram.java new file mode 100644 index 00000000000..74cc7db4e82 --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/AbstractPrometheusHistogram.java @@ -0,0 +1,113 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import static org.hyperledger.besu.metrics.prometheus.PrometheusCollector.addLabelValues; +import static org.hyperledger.besu.metrics.prometheus.PrometheusCollector.getLabelValues; + +import org.hyperledger.besu.metrics.Observation; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +import java.util.ArrayList; +import java.util.stream.Stream; + +import io.prometheus.metrics.core.metrics.Histogram; +import io.prometheus.metrics.model.registry.PrometheusRegistry; + +/** + * Abstract base class for Prometheus histogram collectors. A histogram samples durations and counts + * them in configurable buckets. * It also provides a sum of all observed values. + */ +abstract class AbstractPrometheusHistogram extends CategorizedPrometheusCollector { + protected Histogram histogram; + + protected AbstractPrometheusHistogram( + final MetricCategory category, + final String name, + final String help, + final double[] buckets, + final String... labelNames) { + super(category, name); + this.histogram = + Histogram.builder() + .name(this.prefixedName) + .help(help) + .labelNames(labelNames) + .classicOnly() + .classicUpperBounds(buckets) + .build(); + } + + @Override + public String getIdentifier() { + return histogram.getPrometheusName(); + } + + @Override + public void register(final PrometheusRegistry registry) { + registry.register(histogram); + } + + @Override + public void unregister(final PrometheusRegistry registry) { + registry.unregister(histogram); + } + + @Override + public Stream streamObservations() { + final var snapshot = histogram.collect(); + return snapshot.getDataPoints().stream() + .flatMap( + dataPoint -> { + if (!dataPoint.hasClassicHistogramData()) { + throw new IllegalStateException("Only classic histogram are supported"); + } + + final var labelValues = getLabelValues(dataPoint.getLabels()); + final var classicBuckets = dataPoint.getClassicBuckets(); + final var observations = new ArrayList(classicBuckets.size() + 2); + + if (dataPoint.hasSum()) { + observations.add( + new Observation( + category, name, dataPoint.getSum(), addLabelValues(labelValues, "sum"))); + } + + if (dataPoint.hasCount()) { + observations.add( + new Observation( + category, + name, + dataPoint.getCount(), + addLabelValues(labelValues, "count"))); + } + + classicBuckets.stream() + .forEach( + bucket -> + observations.add( + new Observation( + category, + name, + bucket.getCount(), + addLabelValues( + labelValues, + "bucket", + Double.toString(bucket.getUpperBound()))))); + + return observations.stream(); + }); + } +} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/AbstractPrometheusSummary.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/AbstractPrometheusSummary.java new file mode 100644 index 00000000000..6de25970694 --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/AbstractPrometheusSummary.java @@ -0,0 +1,132 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import static org.hyperledger.besu.metrics.prometheus.PrometheusCollector.addLabelValues; +import static org.hyperledger.besu.metrics.prometheus.PrometheusCollector.getLabelValues; + +import org.hyperledger.besu.metrics.Observation; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +import java.util.ArrayList; +import java.util.stream.Stream; + +import io.prometheus.metrics.model.registry.Collector; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; + +/** + * Abstract base class for Prometheus summary collectors. A summary provides a total count of + * observations and a sum of all observed values, it calculates configurable quantiles over a + * sliding time window. + */ +abstract class AbstractPrometheusSummary extends CategorizedPrometheusCollector { + /** The Prometheus collector */ + protected Collector collector; + + /** + * Constructs a new AbstractPrometheusSummary. + * + * @param category The {@link MetricCategory} this collector is assigned to + * @param name The name of this collector + */ + protected AbstractPrometheusSummary(final MetricCategory category, final String name) { + super(category, name); + } + + /** + * Gets the identifier for this collector. + * + * @return The Prometheus name of the collector + */ + @Override + public String getIdentifier() { + return collector.getPrometheusName(); + } + + /** + * Registers this collector with the given Prometheus registry. + * + * @param registry The Prometheus registry to register this collector with + */ + @Override + public void register(final PrometheusRegistry registry) { + registry.register(collector); + } + + /** + * Unregisters this collector from the given Prometheus registry. + * + * @param registry The Prometheus registry to unregister this collector from + */ + @Override + public void unregister(final PrometheusRegistry registry) { + registry.unregister(collector); + } + + /** + * Collects the summary snapshot from the Prometheus collector. + * + * @return The collected summary snapshot + */ + private SummarySnapshot collect() { + return (SummarySnapshot) collector.collect(); + } + + /** + * Streams the observations from the collected summary snapshot. + * + * @return A stream of observations + */ + @Override + public Stream streamObservations() { + return collect().getDataPoints().stream() + .flatMap( + dataPoint -> { + final var labelValues = getLabelValues(dataPoint.getLabels()); + final var quantiles = dataPoint.getQuantiles(); + final var observations = new ArrayList(quantiles.size() + 2); + + if (dataPoint.hasSum()) { + observations.add( + new Observation( + category, name, dataPoint.getSum(), addLabelValues(labelValues, "sum"))); + } + + if (dataPoint.hasCount()) { + observations.add( + new Observation( + category, + name, + dataPoint.getCount(), + addLabelValues(labelValues, "count"))); + } + + quantiles.forEach( + quantile -> + observations.add( + new Observation( + category, + name, + quantile.getValue(), + addLabelValues( + labelValues, + "quantile", + Double.toString(quantile.getQuantile()))))); + + return observations.stream(); + }); + } +} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/AbstractPrometheusSuppliedValueCollector.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/AbstractPrometheusSuppliedValueCollector.java new file mode 100644 index 00000000000..1295930a1bb --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/AbstractPrometheusSuppliedValueCollector.java @@ -0,0 +1,96 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import org.hyperledger.besu.metrics.Observation; +import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedMetric; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.DoubleSupplier; +import java.util.stream.Stream; + +import io.prometheus.metrics.model.registry.Collector; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; + +/** + * Abstract base class for Prometheus supplied value collectors. A supplied value collector is one + * which actual value is kept outside the metric system, for example in an external library or to + * calculate the value only on demand when a metric scrape occurs. This class provides common + * functionality for Prometheus supplied value collectors. + */ +abstract class AbstractPrometheusSuppliedValueCollector extends CategorizedPrometheusCollector + implements LabelledSuppliedMetric { + /** The collector */ + protected final Collector collector; + + /** Map label values with the collector callback data */ + protected final Map, CallbackData> labelledCallbackData = new ConcurrentHashMap<>(); + + protected AbstractPrometheusSuppliedValueCollector( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + super(category, name); + this.collector = createCollector(help, labelNames); + } + + protected abstract Collector createCollector(final String help, final String... labelNames); + + @Override + public void labels(final DoubleSupplier valueSupplier, final String... labelValues) { + final var valueList = List.of(labelValues); + if (labelledCallbackData.putIfAbsent(valueList, new CallbackData(valueSupplier, labelValues)) + != null) { + throw new IllegalArgumentException( + String.format("A collector has already been created for label values %s", valueList)); + } + } + + @Override + public String getIdentifier() { + return collector.getPrometheusName(); + } + + @Override + public void register(final PrometheusRegistry registry) { + registry.register(collector); + } + + @Override + public void unregister(final PrometheusRegistry registry) { + registry.unregister(collector); + } + + @Override + public Stream streamObservations() { + final var snapshot = collector.collect(); + return snapshot.getDataPoints().stream().map(this::convertToObservation); + } + + /** + * Convert the collected sample to an observation + * + * @param sample the collected sample + * @return an observation + */ + protected abstract Observation convertToObservation(final DataPointSnapshot sample); + + protected record CallbackData(DoubleSupplier valueSupplier, String[] labelValues) {} +} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/CategorizedPrometheusCollector.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/CategorizedPrometheusCollector.java new file mode 100644 index 00000000000..753968966be --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/CategorizedPrometheusCollector.java @@ -0,0 +1,50 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +/** A Prometheus collector that is assigned to a category */ +public abstract class CategorizedPrometheusCollector implements PrometheusCollector { + /** The {@link MetricCategory} this collector is assigned to */ + protected final MetricCategory category; + + /** The name of this collector */ + protected final String name; + + /** The prefixed name of this collector */ + protected final String prefixedName; + + /** + * Create a new collector assigned to the given category and with the given name, and computed the + * prefixed name. + * + * @param category The {@link MetricCategory} this collector is assigned to + * @param name The name of this collector + */ + protected CategorizedPrometheusCollector(final MetricCategory category, final String name) { + this.category = category; + this.name = name; + this.prefixedName = prefixedName(category, name); + } + + private static String categoryPrefix(final MetricCategory category) { + return category.getApplicationPrefix().orElse("") + category.getName() + "_"; + } + + private static String prefixedName(final MetricCategory category, final String name) { + return categoryPrefix(category) + name; + } +} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/CurrentValueCollector.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/CurrentValueCollector.java deleted file mode 100644 index fdcc32bafdf..00000000000 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/CurrentValueCollector.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.metrics.prometheus; - -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; - -import java.util.List; -import java.util.function.DoubleSupplier; - -import io.prometheus.client.Collector; -import io.prometheus.client.Collector.MetricFamilySamples.Sample; - -class CurrentValueCollector extends Collector { - - private final String metricName; - private final String help; - private final DoubleSupplier valueSupplier; - private final List labelNames; - private final List labelValues; - - public CurrentValueCollector( - final String metricName, final String help, final DoubleSupplier valueSupplier) { - this(metricName, help, emptyList(), emptyList(), valueSupplier); - } - - public CurrentValueCollector( - final String metricName, - final String help, - final List labelNames, - final List labelValues, - final DoubleSupplier valueSupplier) { - this.metricName = metricName; - this.help = help; - this.valueSupplier = valueSupplier; - this.labelNames = labelNames; - this.labelValues = labelValues; - } - - @Override - public List collect() { - final Sample sample = - new Sample(metricName, labelNames, labelValues, valueSupplier.getAsDouble()); - return singletonList( - new MetricFamilySamples(metricName, Type.GAUGE, help, singletonList(sample))); - } -} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsHttpService.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsHttpService.java index 94a198dc0e4..48045e4415b 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsHttpService.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsHttpService.java @@ -15,61 +15,46 @@ package org.hyperledger.besu.metrics.prometheus; import static com.google.common.base.Preconditions.checkArgument; +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import org.hyperledger.besu.metrics.MetricsService; -import org.hyperledger.besu.plugin.services.MetricsSystem; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.OutputStreamWriter; import java.net.InetSocketAddress; -import java.net.SocketException; -import java.nio.charset.StandardCharsets; import java.util.Locale; import java.util.Optional; -import java.util.Set; -import java.util.TreeSet; import java.util.concurrent.CompletableFuture; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.prometheus.client.exporter.common.TextFormat; -import io.vertx.core.Handler; -import io.vertx.core.Vertx; -import io.vertx.core.http.HttpMethod; -import io.vertx.core.http.HttpServer; -import io.vertx.core.http.HttpServerOptions; -import io.vertx.core.http.HttpServerResponse; +import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpPrincipal; +import io.prometheus.metrics.exporter.httpserver.DefaultHandler; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.vertx.core.net.HostAndPort; -import io.vertx.ext.web.Router; -import io.vertx.ext.web.RoutingContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** The Metrics http service. */ public class MetricsHttpService implements MetricsService { private static final Logger LOG = LoggerFactory.getLogger(MetricsHttpService.class); - + private static final Authenticator.Result AUTHORIZED = + new Authenticator.Success(new HttpPrincipal("metrics", "metrics")); + private static final Authenticator.Result NOT_AUTHORIZED = new Authenticator.Failure(403); private static final InetSocketAddress EMPTY_SOCKET_ADDRESS = new InetSocketAddress("0.0.0.0", 0); - private final Vertx vertx; private final MetricsConfiguration config; - private final MetricsSystem metricsSystem; - - private HttpServer httpServer; + private final PrometheusMetricsSystem metricsSystem; + private HTTPServer httpServer; /** * Instantiates a new Metrics http service. * - * @param vertx the vertx * @param configuration the configuration * @param metricsSystem the metrics system */ public MetricsHttpService( - final Vertx vertx, - final MetricsConfiguration configuration, - final MetricsSystem metricsSystem) { + final MetricsConfiguration configuration, final PrometheusMetricsSystem metricsSystem) { validateConfig(configuration); - this.vertx = vertx; this.config = configuration; this.metricsSystem = metricsSystem; } @@ -85,78 +70,39 @@ private void validateConfig(final MetricsConfiguration config) { @Override public CompletableFuture start() { LOG.info("Starting metrics http service on {}:{}", config.getHost(), config.getPort()); - // Create the HTTP server and a router object. - httpServer = - vertx.createHttpServer( - new HttpServerOptions() - .setHost(config.getHost()) - .setPort(config.getPort()) - .setIdleTimeout(config.getIdleTimeout()) - .setHandle100ContinueAutomatically(true) - .setCompressionSupported(true)); - - final Router router = Router.router(vertx); - - // Verify Host header. - router.route().handler(checkAllowlistHostHeader()); - - // Endpoint for AWS health check. - router.route("/").method(HttpMethod.GET).handler(this::handleEmptyRequest); - // Endpoint for Prometheus metrics monitoring. - router.route("/metrics").method(HttpMethod.GET).handler(this::metricsRequest); + try { + httpServer = + HTTPServer.builder() + .hostname(config.getHost()) + .port(config.getPort()) + .registry(metricsSystem.getRegistry()) + .authenticator( + new Authenticator() { + @Override + public Result authenticate(final HttpExchange exch) { + return checkAllowlistHostHeader(exch); + } + }) + .defaultHandler(new RestrictedDefaultHandler()) + .buildAndStart(); - final CompletableFuture resultFuture = new CompletableFuture<>(); - httpServer - .requestHandler(router) - .listen( - res -> { - if (!res.failed()) { - resultFuture.complete(null); - final int actualPort = httpServer.actualPort(); - config.setActualPort(actualPort); - LOG.info( - "Metrics service started and listening on {}:{}", config.getHost(), actualPort); - return; - } - httpServer = null; - final Throwable cause = res.cause(); - if (cause instanceof SocketException) { - resultFuture.completeExceptionally( - new RuntimeException( - String.format( - "Failed to bind metrics listener to %s:%s (actual port %s): %s", - config.getHost(), - config.getPort(), - config.getActualPort(), - cause.getMessage()))); - return; - } - resultFuture.completeExceptionally(cause); - }); - return resultFuture; + return CompletableFuture.completedFuture(null); + } catch (final Throwable e) { + return CompletableFuture.failedFuture(e); + } } - private Handler checkAllowlistHostHeader() { - return event -> { - final Optional hostHeader = getAndValidateHostHeader(event); - if (config.getHostsAllowlist().contains("*") - || (hostHeader.isPresent() && hostIsInAllowlist(hostHeader.get()))) { - event.next(); - } else { - final HttpServerResponse response = event.response(); - if (!response.closed()) { - response - .setStatusCode(403) - .putHeader("Content-Type", "application/json; charset=utf-8") - .end("{\"message\":\"Host not authorized.\"}"); - } - } - }; - } + private Authenticator.Result checkAllowlistHostHeader(final HttpExchange exch) { + if (config.getHostsAllowlist().contains("*")) { + return AUTHORIZED; + } - private Optional getAndValidateHostHeader(final RoutingContext event) { - return Optional.ofNullable(event.request().authority()).map(HostAndPort::host); + return Optional.ofNullable(exch.getRequestHeaders().getFirst("Host")) + .map(host -> HostAndPort.parseAuthority(host, -1).host()) + .filter(this::hostIsInAllowlist) + .map(unused -> AUTHORIZED) + .orElse(NOT_AUTHORIZED); } private boolean hostIsInAllowlist(final String hostHeader) { @@ -179,56 +125,12 @@ public CompletableFuture stop() { return CompletableFuture.completedFuture(null); } - final CompletableFuture resultFuture = new CompletableFuture<>(); - httpServer.close( - res -> { - if (res.failed()) { - resultFuture.completeExceptionally(res.cause()); - } else { - httpServer = null; - resultFuture.complete(null); - } - }); - return resultFuture; - } - - private void metricsRequest(final RoutingContext routingContext) { - final Set names = new TreeSet<>(routingContext.queryParam("name[]")); - final HttpServerResponse response = routingContext.response(); - vertx.executeBlocking( - future -> { - try { - final ByteArrayOutputStream metrics = new ByteArrayOutputStream(16 * 1024); - final OutputStreamWriter osw = new OutputStreamWriter(metrics, StandardCharsets.UTF_8); - TextFormat.write004( - osw, - ((PrometheusMetricsSystem) (metricsSystem)) - .getRegistry() - .filteredMetricFamilySamples(names)); - osw.flush(); - osw.close(); - metrics.flush(); - metrics.close(); - future.complete(metrics.toString(StandardCharsets.UTF_8.name())); - } catch (final IOException ioe) { - future.fail(ioe); - } - }, - false, - (res) -> { - if (response.closed()) { - // Request for metrics closed before response was generated - return; - } - if (res.failed()) { - LOG.error("Request for metrics failed", res.cause()); - response.setStatusCode(HttpResponseStatus.INTERNAL_SERVER_ERROR.code()).end(); - } else { - response.setStatusCode(HttpResponseStatus.OK.code()); - response.putHeader("Content-Type", TextFormat.CONTENT_TYPE_004); - response.end(res.result()); - } - }); + try { + httpServer.stop(); + return CompletableFuture.completedFuture(null); + } catch (final Throwable e) { + return CompletableFuture.failedFuture(e); + } } /** @@ -240,7 +142,7 @@ InetSocketAddress socketAddress() { if (httpServer == null) { return EMPTY_SOCKET_ADDRESS; } - return new InetSocketAddress(config.getHost(), httpServer.actualPort()); + return new InetSocketAddress(config.getHost(), httpServer.getPort()); } @Override @@ -248,11 +150,21 @@ public Optional getPort() { if (httpServer == null) { return Optional.empty(); } - return Optional.of(httpServer.actualPort()); + return Optional.of(httpServer.getPort()); } - // Facilitate remote health-checks in AWS, inter alia. - private void handleEmptyRequest(final RoutingContext routingContext) { - routingContext.response().setStatusCode(201).end(); + private static class RestrictedDefaultHandler extends DefaultHandler { + @Override + public void handle(final HttpExchange exchange) throws IOException { + if (!exchange.getRequestURI().getPath().equals("/")) { + try { + exchange.sendResponseHeaders(HTTP_NOT_FOUND, -1); + } finally { + exchange.close(); + } + } else { + super.handle(exchange); + } + } } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsPushGatewayService.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsPushGatewayService.java index fa9cf53e809..ad60a2fd203 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsPushGatewayService.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsPushGatewayService.java @@ -26,7 +26,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import io.prometheus.client.exporter.PushGateway; +import io.prometheus.metrics.exporter.pushgateway.PushGateway; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,7 +71,12 @@ public CompletableFuture start() { config.getPushHost(), config.getPushPort()); - pushGateway = new PushGateway(config.getPushHost() + ":" + config.getPushPort()); + pushGateway = + PushGateway.builder() + .registry(((PrometheusMetricsSystem) metricsSystem).getRegistry()) + .address(config.getPushHost() + ":" + config.getPushPort()) + .job(config.getPrometheusJob()) + .build(); // Create the executor scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); @@ -91,7 +96,7 @@ public CompletableFuture stop() { scheduledExecutorService.shutdownNow(); scheduledExecutorService.awaitTermination(30, TimeUnit.SECONDS); try { - pushGateway.delete(config.getPrometheusJob()); + pushGateway.delete(); } catch (final Exception e) { LOG.error("Could not clean up results on the Prometheus Push Gateway.", e); // Do not complete exceptionally, the gateway may be down and failures @@ -112,8 +117,7 @@ public Optional getPort() { private void pushMetrics() { try { - pushGateway.pushAdd( - ((PrometheusMetricsSystem) metricsSystem).getRegistry(), config.getPrometheusJob()); + pushGateway.pushAdd(); } catch (final IOException e) { LOG.warn("Could not push metrics", e); } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCollector.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCollector.java new file mode 100644 index 00000000000..1e2da8ff00b --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCollector.java @@ -0,0 +1,82 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import org.hyperledger.besu.metrics.Observation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; + +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Label; +import io.prometheus.metrics.model.snapshots.Labels; + +/** Wraps a native Prometheus collector inside the metric system */ +public interface PrometheusCollector { + + /** + * Get the identifier of the collector + * + * @return the identifier of the collector + */ + String getIdentifier(); + + /** + * Register this collector to the specified registry + * + * @param registry the registry + */ + void register(final PrometheusRegistry registry); + + /** + * Unregister this collector from the specified registry + * + * @param registry the registry + */ + void unregister(final PrometheusRegistry registry); + + /** + * Stream the data points of this collector + * + * @return a stream of the data points of this collector + */ + Stream streamObservations(); + + /** + * Utility to get the label values as strings from native Prometheus labels + * + * @param labels the Prometheus labels + * @return the label values as strings + */ + static List getLabelValues(final Labels labels) { + return labels.stream().map(Label::getValue).toList(); + } + + /** + * Add new values to an existing list of label values + * + * @param labelValues existing list of label values + * @param values the values to add + * @return a new list with new values appended to the original list + */ + static List addLabelValues(final List labelValues, final String... values) { + final var newList = new ArrayList(labelValues.size() + values.length); + newList.addAll(labelValues); + Collections.addAll(newList, values); + return newList; + } +} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCounter.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCounter.java index 85b3750b778..b712c29a732 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCounter.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCounter.java @@ -14,34 +14,88 @@ */ package org.hyperledger.besu.metrics.prometheus; +import static org.hyperledger.besu.metrics.prometheus.PrometheusCollector.getLabelValues; + +import org.hyperledger.besu.metrics.Observation; import org.hyperledger.besu.plugin.services.metrics.Counter; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +import java.util.stream.Stream; -class PrometheusCounter implements LabelledMetric { +import io.prometheus.metrics.core.datapoints.CounterDataPoint; +import io.prometheus.metrics.model.registry.PrometheusRegistry; - private final io.prometheus.client.Counter counter; +/** + * A Prometheus counter implementation for Besu metrics. This class provides a Prometheus counter + * where the actual value is kept internally by the collector and methods are provided to increase + * the value when needed. + */ +class PrometheusCounter extends CategorizedPrometheusCollector implements LabelledMetric { + private final io.prometheus.metrics.core.metrics.Counter counter; - public PrometheusCounter(final io.prometheus.client.Counter counter) { - this.counter = counter; + public PrometheusCounter( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + super(category, name); + this.counter = + io.prometheus.metrics.core.metrics.Counter.builder() + .name(this.prefixedName) + .help(help) + .labelNames(labelNames) + .build(); } @Override public Counter labels(final String... labels) { - return new UnlabelledCounter(counter.labels(labels)); + return new UnlabelledCounter(counter.labelValues(labels)); } - private static class UnlabelledCounter implements Counter { - private final io.prometheus.client.Counter.Child counter; + @Override + public String getIdentifier() { + return counter.getPrometheusName(); + } - private UnlabelledCounter(final io.prometheus.client.Counter.Child counter) { - this.counter = counter; - } + @Override + public void register(final PrometheusRegistry registry) { + registry.register(counter); + } + + @Override + public void unregister(final PrometheusRegistry registry) { + registry.unregister(counter); + } + + /** + * Streams the observations from the collected counter data points. + * + * @return A stream of observations + */ + @Override + public Stream streamObservations() { + return counter.collect().getDataPoints().stream() + .map( + sample -> + new Observation( + category, name, sample.getValue(), getLabelValues(sample.getLabels()))); + } + + /** A private record class representing an unlabelled counter. */ + private record UnlabelledCounter(CounterDataPoint counter) implements Counter { + /** Increments the counter by one. */ @Override public void inc() { counter.inc(); } + /** + * Increments the counter by the specified amount. + * + * @param amount The amount to increment the counter by + */ @Override public void inc(final long amount) { counter.inc((double) amount); diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGuavaCache.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGuavaCache.java new file mode 100644 index 00000000000..4ca101abe1d --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGuavaCache.java @@ -0,0 +1,171 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import static org.hyperledger.besu.metrics.prometheus.PrometheusCollector.getLabelValues; + +import org.hyperledger.besu.metrics.Observation; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.ToDoubleFunction; +import java.util.stream.Stream; + +import com.google.common.cache.Cache; +import io.prometheus.metrics.instrumentation.guava.CacheMetricsCollector; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.vertx.core.impl.ConcurrentHashSet; + +/** + * A Prometheus Guava cache collector implementation for Besu metrics. This class provides a way to + * expose metrics from Guava caches, it behaves differently from other collectors, since instead of + * having one collector per cache, Prometheus provides only one collector for all caches, so we need + * a Context that wraps the Prometheus single collector and handles its registration, while here we + * keep the abstraction of one Prometheus collector for one Guava cache, and we also verify that + * there is no collector name clash. + */ +class PrometheusGuavaCache extends CategorizedPrometheusCollector { + /** Use to reduce the possibility of a name clash with other collectors */ + private static final String NAME_PREFIX = "__guavaCacheMetricsCollector__"; + + private final Cache cache; + private final Context context; + + public PrometheusGuavaCache( + final MetricCategory category, + final Context context, + final String name, + final Cache cache) { + super(category, name); + if (context.alreadyExists(name)) { + throw new IllegalStateException("Cache already registered: " + name); + } + this.cache = cache; + this.context = context; + } + + @Override + public String getIdentifier() { + return category.getName() + "." + NAME_PREFIX + "." + name; + } + + @Override + public void register(final PrometheusRegistry registry) { + context.registerCache(registry, name, cache); + } + + @Override + public void unregister(final PrometheusRegistry registry) { + context.unregisterCache(registry, name); + } + + @Override + public Stream streamObservations() { + return context.streamObservations(category, name); + } + + /** + * Since Prometheus provides only one collector for all Guava caches, we only need to register + * that collector once when the first Besu Guava cache collector is created, and unregister it + * when the last is unregistered, so we have this context to keep track of that and also manage + * the observations stream. + */ + static class Context { + private static final Map> + COLLECTOR_VALUE_EXTRACTORS = + Map.of( + "guava_cache_eviction", Context::counterValueExtractor, + "guava_cache_hit", Context::counterValueExtractor, + "guava_cache_miss", Context::counterValueExtractor, + "guava_cache_requests", Context::counterValueExtractor, + "guava_cache_size", Context::gaugeValueExtractor); + + private final CacheMetricsCollector cacheMetricsCollector = new CacheMetricsCollector(); + private final Set cacheNames = new ConcurrentHashSet<>(); + private final AtomicBoolean collectorRegistered = new AtomicBoolean(false); + + boolean alreadyExists(final String name) { + return cacheNames.contains(name); + } + + void registerCache( + final PrometheusRegistry registry, final String name, final Cache cache) { + cacheMetricsCollector.addCache(name, cache); + cacheNames.add(name); + if (collectorRegistered.compareAndSet(false, true)) { + registry.register(cacheMetricsCollector); + } + } + + void unregisterCache(final PrometheusRegistry registry, final String name) { + cacheMetricsCollector.removeCache(name); + cacheNames.remove(name); + if (cacheNames.isEmpty() && collectorRegistered.compareAndSet(true, false)) { + registry.unregister(cacheMetricsCollector); + } + } + + void clear() { + cacheNames.forEach(cacheMetricsCollector::removeCache); + cacheNames.clear(); + collectorRegistered.set(false); + } + + private Stream streamObservations( + final MetricCategory category, final String cacheName) { + return cacheMetricsCollector.collect().stream() + .flatMap(ms -> convertToObservations(category, cacheName, ms)); + } + + private static Stream convertToObservations( + final MetricCategory category, final String cacheName, final MetricSnapshot snapshot) { + final var prometheusName = snapshot.getMetadata().getPrometheusName(); + if (COLLECTOR_VALUE_EXTRACTORS.containsKey(prometheusName)) { + return snapshotToObservations(category, cacheName, prometheusName, snapshot); + } + return Stream.empty(); + } + + private static Stream snapshotToObservations( + final MetricCategory category, + final String cacheName, + final String prometheusName, + final MetricSnapshot snapshot) { + return snapshot.getDataPoints().stream() + .filter(gdps -> gdps.getLabels().get("cache").equals(cacheName)) + .map( + gdps -> + new Observation( + category, + prometheusName, + COLLECTOR_VALUE_EXTRACTORS.get(prometheusName).applyAsDouble(gdps), + getLabelValues(gdps.getLabels()))); + } + + private static double gaugeValueExtractor(final DataPointSnapshot snapshot) { + return ((GaugeSnapshot.GaugeDataPointSnapshot) snapshot).getValue(); + } + + private static double counterValueExtractor(final DataPointSnapshot snapshot) { + return ((CounterSnapshot.CounterDataPointSnapshot) snapshot).getValue(); + } + } +} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusHistogram.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusHistogram.java index 825f967a64d..53c315ee9b8 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusHistogram.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusHistogram.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -16,30 +16,26 @@ import org.hyperledger.besu.plugin.services.metrics.Histogram; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; -class PrometheusHistogram implements LabelledMetric { - - private final io.prometheus.client.Histogram histogram; - - public PrometheusHistogram(final io.prometheus.client.Histogram histogram) { - this.histogram = histogram; +/** + * A Prometheus histogram. A histogram samples durations and counts them in configurable buckets. It + * also provides a sum of all observed values. + */ +class PrometheusHistogram extends AbstractPrometheusHistogram implements LabelledMetric { + + public PrometheusHistogram( + final MetricCategory category, + final String name, + final String help, + final double[] buckets, + final String... labelNames) { + super(category, name, help, buckets, labelNames); } @Override public Histogram labels(final String... labels) { - return new UnlabelledHistogram(histogram.labels(labels)); - } - - private static class UnlabelledHistogram implements Histogram { - private final io.prometheus.client.Histogram.Child amount; - - private UnlabelledHistogram(final io.prometheus.client.Histogram.Child amount) { - this.amount = amount; - } - - @Override - public void observe(final double amount) { - this.amount.observe(amount); - } + final var ddp = histogram.labelValues(labels); + return ddp::observe; } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java index 53d71382640..a207cc5b70e 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java @@ -14,61 +14,65 @@ */ package org.hyperledger.besu.metrics.prometheus; +import static java.util.Map.entry; + import org.hyperledger.besu.metrics.ObservableMetricsSystem; import org.hyperledger.besu.metrics.Observation; import org.hyperledger.besu.metrics.StandardMetricCategory; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.metrics.ExternalSummary; +import org.hyperledger.besu.plugin.services.metrics.Counter; +import org.hyperledger.besu.plugin.services.metrics.Histogram; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedMetric; +import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedSummary; import org.hyperledger.besu.plugin.services.metrics.MetricCategory; import org.hyperledger.besu.plugin.services.metrics.OperationTimer; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.DoubleSupplier; -import java.util.function.Supplier; import java.util.stream.Stream; import com.google.common.cache.Cache; import com.google.common.collect.ImmutableSet; -import io.prometheus.client.Collector; -import io.prometheus.client.Collector.MetricFamilySamples; -import io.prometheus.client.Collector.MetricFamilySamples.Sample; -import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.Counter; -import io.prometheus.client.Histogram; -import io.prometheus.client.Summary; -import io.prometheus.client.guava.cache.CacheMetricsCollector; -import io.prometheus.client.hotspot.BufferPoolsExports; -import io.prometheus.client.hotspot.ClassLoadingExports; -import io.prometheus.client.hotspot.GarbageCollectorExports; -import io.prometheus.client.hotspot.MemoryPoolsExports; -import io.prometheus.client.hotspot.StandardExports; -import io.prometheus.client.hotspot.ThreadExports; +import io.prometheus.metrics.instrumentation.jvm.JvmBufferPoolMetrics; +import io.prometheus.metrics.instrumentation.jvm.JvmClassLoadingMetrics; +import io.prometheus.metrics.instrumentation.jvm.JvmCompilationMetrics; +import io.prometheus.metrics.instrumentation.jvm.JvmGarbageCollectorMetrics; +import io.prometheus.metrics.instrumentation.jvm.JvmMemoryMetrics; +import io.prometheus.metrics.instrumentation.jvm.JvmMemoryPoolAllocationMetrics; +import io.prometheus.metrics.instrumentation.jvm.JvmNativeMemoryMetrics; +import io.prometheus.metrics.instrumentation.jvm.JvmRuntimeInfoMetric; +import io.prometheus.metrics.instrumentation.jvm.JvmThreadsMetrics; +import io.prometheus.metrics.instrumentation.jvm.ProcessMetrics; +import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.vertx.core.impl.ConcurrentHashSet; /** The Prometheus metrics system. */ public class PrometheusMetricsSystem implements ObservableMetricsSystem { - private static final List EXTERNAL_SUMMARY_LABELS = List.of("quantile"); - - private final Map> collectors = new ConcurrentHashMap<>(); - private final CollectorRegistry registry = new CollectorRegistry(true); - private final Map> - cachedCounters = new ConcurrentHashMap<>(); - private final Map> cachedTimers = + private static final Map DEFAULT_SUMMARY_QUANTILES = + Map.ofEntries( + entry(0.2, 0.02), + entry(0.5, 0.05), + entry(0.8, 0.02), + entry(0.95, 0.005), + entry(0.99, 0.001), + entry(1.0, 0.0)); + + private final Map> collectors = + new ConcurrentHashMap<>(); + private final PrometheusRegistry registry = PrometheusRegistry.defaultRegistry; + private final Map> cachedCounters = new ConcurrentHashMap<>(); - private final Map> - cachedHistograms = new ConcurrentHashMap<>(); - private final Set totalSuffixedCounters = new ConcurrentHashSet<>(); - private final Map guavaCacheCollectors = + private final Map> cachedTimers = new ConcurrentHashMap<>(); - private final Set guavaCacheNames = new ConcurrentHashSet<>(); + private final Map> cachedHistograms = + new ConcurrentHashMap<>(); + + private final PrometheusGuavaCache.Context guavaCacheCollectorContext = + new PrometheusGuavaCache.Context(); private final Set enabledCategories; private final boolean timersEnabled; @@ -87,15 +91,19 @@ public PrometheusMetricsSystem( /** Init. */ public void init() { - if (isCategoryEnabled(StandardMetricCategory.PROCESS)) { - registerCollector(StandardMetricCategory.PROCESS, new StandardExports()); - } if (isCategoryEnabled(StandardMetricCategory.JVM)) { - registerCollector(StandardMetricCategory.JVM, new MemoryPoolsExports()); - registerCollector(StandardMetricCategory.JVM, new BufferPoolsExports()); - registerCollector(StandardMetricCategory.JVM, new GarbageCollectorExports()); - registerCollector(StandardMetricCategory.JVM, new ThreadExports()); - registerCollector(StandardMetricCategory.JVM, new ClassLoadingExports()); + JvmThreadsMetrics.builder().register(registry); + JvmBufferPoolMetrics.builder().register(registry); + JvmClassLoadingMetrics.builder().register(registry); + JvmCompilationMetrics.builder().register(registry); + JvmGarbageCollectorMetrics.builder().register(registry); + JvmMemoryMetrics.builder().register(registry); + JvmMemoryPoolAllocationMetrics.builder().register(registry); + JvmNativeMemoryMetrics.builder().register(registry); + JvmRuntimeInfoMetric.builder().register(registry); + } + if (isCategoryEnabled(StandardMetricCategory.PROCESS)) { + ProcessMetrics.builder().register(registry); } } @@ -105,45 +113,20 @@ public Set getEnabledCategories() { } @Override - public LabelledMetric createLabelledCounter( + public LabelledMetric createLabelledCounter( final MetricCategory category, final String name, final String help, final String... labelNames) { - final String metricName = convertToPrometheusCounterName(category, name); return cachedCounters.computeIfAbsent( - metricName, - (k) -> { - if (isCategoryEnabled(category)) { - final Counter counter = Counter.build(metricName, help).labelNames(labelNames).create(); - registerCollector(category, counter); - return new PrometheusCounter(counter); - } else { - return NoOpMetricsSystem.getCounterLabelledMetric(labelNames.length); - } - }); - } - - @Override - public LabelledMetric - createLabelledHistogram( - final MetricCategory category, - final String name, - final String help, - final double[] buckets, - final String... labelNames) { - final String metricName = convertToPrometheusName(category, name); - return cachedHistograms.computeIfAbsent( - metricName, + CachedMetricKey.of(category, name), k -> { if (isCategoryEnabled(category)) { - final Histogram histogram = - Histogram.build(metricName, help).labelNames(labelNames).buckets(buckets).create(); - registerCollector(category, histogram); - return new PrometheusHistogram(histogram); - } else { - return NoOpMetricsSystem.getHistogramLabelledMetric(labelNames.length); + final var counter = new PrometheusCounter(category, name, help, labelNames); + registerCollector(category, counter); + return counter; } + return NoOpMetricsSystem.getCounterLabelledMetric(labelNames.length); }); } @@ -153,26 +136,16 @@ public LabelledMetric createLabelledTimer( final String name, final String help, final String... labelNames) { - final String metricName = convertToPrometheusName(category, name); return cachedTimers.computeIfAbsent( - metricName, - (k) -> { + CachedMetricKey.of(category, name), + k -> { if (timersEnabled && isCategoryEnabled(category)) { - final Summary summary = - Summary.build(metricName, help) - .quantile(0.2, 0.02) - .quantile(0.5, 0.05) - .quantile(0.8, 0.02) - .quantile(0.95, 0.005) - .quantile(0.99, 0.001) - .quantile(1.0, 0) - .labelNames(labelNames) - .create(); + final var summary = + new PrometheusTimer(category, name, help, DEFAULT_SUMMARY_QUANTILES, labelNames); registerCollector(category, summary); - return new PrometheusTimer(summary); - } else { - return NoOpMetricsSystem.getOperationTimerLabelledMetric(labelNames.length); + return summary; } + return NoOpMetricsSystem.getOperationTimerLabelledMetric(labelNames.length); }); } @@ -182,85 +155,61 @@ public LabelledMetric createSimpleLabelledTimer( final String name, final String help, final String... labelNames) { - final String metricName = convertToPrometheusName(category, name); return cachedTimers.computeIfAbsent( - metricName, - (k) -> { + CachedMetricKey.of(category, name), + k -> { if (timersEnabled && isCategoryEnabled(category)) { - final Histogram histogram = - Histogram.build(metricName, help).labelNames(labelNames).buckets(1D).create(); + final var histogram = + new PrometheusSimpleTimer(category, name, help, new double[] {1D}, labelNames); registerCollector(category, histogram); - return new PrometheusSimpleTimer(histogram); - } else { - return NoOpMetricsSystem.getOperationTimerLabelledMetric(labelNames.length); + return histogram; } + return NoOpMetricsSystem.getOperationTimerLabelledMetric(labelNames.length); }); } @Override - public void createGauge( + public LabelledMetric createLabelledHistogram( final MetricCategory category, final String name, final String help, - final DoubleSupplier valueSupplier) { - final String metricName = convertToPrometheusName(category, name); - if (isCategoryEnabled(category)) { - final Collector collector = new CurrentValueCollector(metricName, help, valueSupplier); - registerCollector(category, collector); - } + final double[] buckets, + final String... labelNames) { + return cachedHistograms.computeIfAbsent( + CachedMetricKey.of(category, name), + k -> { + if (isCategoryEnabled(category)) { + final var histogram = + new PrometheusHistogram(category, name, help, buckets, labelNames); + registerCollector(category, histogram); + return histogram; + } + return NoOpMetricsSystem.getHistogramLabelledMetric(labelNames.length); + }); } @Override - public void trackExternalSummary( + public LabelledSuppliedSummary createLabelledSuppliedSummary( final MetricCategory category, final String name, final String help, - final Supplier summarySupplier) { + final String... labelNames) { if (isCategoryEnabled(category)) { - final var externalSummaryCollector = - new Collector() { - @Override - public List collect() { - final var externalSummary = summarySupplier.get(); - - final var quantileValues = - externalSummary.quantiles().stream() - .map( - quantile -> - new Sample( - name, - EXTERNAL_SUMMARY_LABELS, - List.of(Double.toString(quantile.quantile())), - quantile.value())) - .toList(); - - return List.of( - new MetricFamilySamples( - name, Type.SUMMARY, "RocksDB histogram for " + name, quantileValues)); - } - }; - - registerCollector(category, externalSummaryCollector); + final PrometheusSuppliedSummary summary = + new PrometheusSuppliedSummary(category, name, help, labelNames); + registerCollector(category, summary); + return summary; } + return NoOpMetricsSystem.getLabelledSuppliedSummary(labelNames.length); } @Override public void createGuavaCacheCollector( final MetricCategory category, final String name, final Cache cache) { if (isCategoryEnabled(category)) { - if (guavaCacheNames.contains(name)) { - throw new IllegalStateException("Cache already registered: " + name); - } - guavaCacheNames.add(name); - final var guavaCacheCollector = - guavaCacheCollectors.computeIfAbsent( - category, - unused -> { - final var cmc = new CacheMetricsCollector(); - registerCollector(category, cmc); - return cmc; - }); - guavaCacheCollector.addCache(name, cache); + final var cacheCollector = + new PrometheusGuavaCache(category, guavaCacheCollectorContext, name, cache); + registerCollector(category, cacheCollector); } } @@ -270,7 +219,13 @@ public LabelledSuppliedMetric createLabelledSuppliedCounter( final String name, final String help, final String... labelNames) { - return createLabelledSuppliedMetric(category, Collector.Type.COUNTER, name, help, labelNames); + if (isCategoryEnabled(category)) { + final PrometheusSuppliedCounter counter = + new PrometheusSuppliedCounter(category, name, help, labelNames); + registerCollector(category, counter); + return counter; + } + return NoOpMetricsSystem.getLabelledSuppliedMetric(labelNames.length); } @Override @@ -279,53 +234,38 @@ public LabelledSuppliedMetric createLabelledSuppliedGauge( final String name, final String help, final String... labelNames) { - return createLabelledSuppliedMetric(category, Collector.Type.GAUGE, name, help, labelNames); - } - - private LabelledSuppliedMetric createLabelledSuppliedMetric( - final MetricCategory category, - final Collector.Type type, - final String name, - final String help, - final String... labelNames) { - final String metricName = convertToPrometheusName(category, name); if (isCategoryEnabled(category)) { - final PrometheusSuppliedValueCollector suppliedValueCollector = - new PrometheusSuppliedValueCollector(type, metricName, help, List.of(labelNames)); - registerCollector(category, suppliedValueCollector); - return suppliedValueCollector; + final PrometheusSuppliedGauge gauge = + new PrometheusSuppliedGauge(category, name, help, labelNames); + registerCollector(category, gauge); + return gauge; } return NoOpMetricsSystem.getLabelledSuppliedMetric(labelNames.length); } - private void registerCollector(final MetricCategory category, final Collector collector) { - final Collection categoryCollectors = - this.collectors.computeIfAbsent( - category, key -> Collections.newSetFromMap(new ConcurrentHashMap<>())); - - final List newSamples = - collector.collect().stream().map(metricFamilySamples -> metricFamilySamples.name).toList(); + private void registerCollector( + final MetricCategory category, final PrometheusCollector collector) { + final Collection categoryCollectors = + this.collectors.computeIfAbsent(category, key -> new ConcurrentHashSet<>()); + // unregister if already present categoryCollectors.stream() - .filter( - c -> - c.collect().stream() - .anyMatch(metricFamilySamples -> newSamples.contains(metricFamilySamples.name))) + .filter(c -> c.getIdentifier().equals(collector.getIdentifier())) .findFirst() .ifPresent( c -> { categoryCollectors.remove(c); - registry.unregister(c); + c.unregister(registry); }); - categoryCollectors.add(collector.register(registry)); + collector.register(registry); + categoryCollectors.add(collector); } @Override public Stream streamObservations(final MetricCategory category) { return collectors.getOrDefault(category, Collections.emptySet()).stream() - .flatMap(collector -> collector.collect().stream()) - .flatMap(familySamples -> convertSamplesToObservations(category, familySamples)); + .flatMap(PrometheusCollector::streamObservations); } @Override @@ -333,137 +273,22 @@ public Stream streamObservations() { return collectors.keySet().stream().flatMap(this::streamObservations); } + PrometheusRegistry getRegistry() { + return registry; + } + @Override public void shutdown() { registry.clear(); collectors.clear(); cachedCounters.clear(); cachedTimers.clear(); - guavaCacheCollectors.clear(); - guavaCacheNames.clear(); - } - - private Stream convertSamplesToObservations( - final MetricCategory category, final MetricFamilySamples familySamples) { - return familySamples.samples.stream() - .map(sample -> createObservationFromSample(category, sample, familySamples)); - } - - private Observation createObservationFromSample( - final MetricCategory category, final Sample sample, final MetricFamilySamples familySamples) { - if (familySamples.type == Collector.Type.HISTOGRAM) { - return convertHistogramSampleNamesToLabels(category, sample, familySamples); - } - if (familySamples.type == Collector.Type.SUMMARY) { - return convertSummarySampleNamesToLabels(category, sample, familySamples); - } - if (familySamples.type == Collector.Type.COUNTER) { - return convertCounterNamesToLabels(category, sample, familySamples); - } - return new Observation( - category, - convertFromPrometheusName(category, sample.name), - sample.value, - sample.labelValues); - } - - private Observation convertCounterNamesToLabels( - final MetricCategory category, final Sample sample, final MetricFamilySamples familySamples) { - final List labelValues = new ArrayList<>(sample.labelValues); - if (sample.name.endsWith("_created")) { - labelValues.add("created"); - } - - return new Observation( - category, - convertFromPrometheusCounterName(category, familySamples.name), - sample.value, - labelValues); - } - - private Observation convertHistogramSampleNamesToLabels( - final MetricCategory category, final Sample sample, final MetricFamilySamples familySamples) { - final List labelValues = new ArrayList<>(sample.labelValues); - if (sample.name.endsWith("_bucket")) { - labelValues.add(labelValues.size() - 1, "bucket"); - } else { - labelValues.add(sample.name.substring(sample.name.lastIndexOf("_") + 1)); - } - return new Observation( - category, - convertFromPrometheusName(category, familySamples.name), - sample.value, - labelValues); - } - - private Observation convertSummarySampleNamesToLabels( - final MetricCategory category, final Sample sample, final MetricFamilySamples familySamples) { - final List labelValues = new ArrayList<>(sample.labelValues); - if (sample.name.endsWith("_sum")) { - labelValues.add("sum"); - } else if (sample.name.endsWith("_count")) { - labelValues.add("count"); - } else if (sample.name.endsWith("_created")) { - labelValues.add("created"); - } else { - labelValues.add(labelValues.size() - 1, "quantile"); - } - return new Observation( - category, - convertFromPrometheusName(category, familySamples.name), - sample.value, - labelValues); - } - - /** - * Convert to prometheus name. - * - * @param category the category - * @param name the name - * @return the name as string - */ - public String convertToPrometheusName(final MetricCategory category, final String name) { - return prometheusPrefix(category) + name; + guavaCacheCollectorContext.clear(); } - /** - * Convert to prometheus counter name. Prometheus adds a _total suffix to the name if not present, - * so we remember if the original name already has it, to be able to convert back correctly - * - * @param category the category - * @param name the name - * @return the name as string - */ - public String convertToPrometheusCounterName(final MetricCategory category, final String name) { - if (name.endsWith("_total")) { - totalSuffixedCounters.add(name); + private record CachedMetricKey(MetricCategory category, String name) { + static CachedMetricKey of(final MetricCategory category, final String name) { + return new CachedMetricKey(category, name); } - return convertToPrometheusName(category, name); - } - - private String convertFromPrometheusName(final MetricCategory category, final String metricName) { - final String prefix = prometheusPrefix(category); - return metricName.startsWith(prefix) ? metricName.substring(prefix.length()) : metricName; - } - - private String convertFromPrometheusCounterName( - final MetricCategory category, final String metricName) { - final String unPrefixedName = convertFromPrometheusName(category, metricName); - return totalSuffixedCounters.contains(unPrefixedName + "_total") - ? unPrefixedName + "_total" - : unPrefixedName; - } - - private String prometheusPrefix(final MetricCategory category) { - return category.getApplicationPrefix().orElse("") + category.getName() + "_"; - } - - /** - * Gets registry. - * - * @return the registry - */ - CollectorRegistry getRegistry() { - return registry; } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java index 24799cb33d2..b3c47de9420 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java @@ -15,21 +15,28 @@ package org.hyperledger.besu.metrics.prometheus; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; import org.hyperledger.besu.plugin.services.metrics.OperationTimer; -import io.prometheus.client.Histogram; - -class PrometheusSimpleTimer implements LabelledMetric { - - private final Histogram histogram; +/** + * An implementation of Besu simple timer backed by a Prometheus histogram. The histogram samples + * durations and counts them in configurable buckets. It also provides a sum of all observed values. + */ +class PrometheusSimpleTimer extends AbstractPrometheusHistogram + implements LabelledMetric { - public PrometheusSimpleTimer(final Histogram histogram) { - this.histogram = histogram; + public PrometheusSimpleTimer( + final MetricCategory category, + final String name, + final String help, + final double[] buckets, + final String... labelNames) { + super(category, name, help, buckets, labelNames); } @Override public OperationTimer labels(final String... labels) { - final Histogram.Child metric = histogram.labels(labels); - return () -> metric.startTimer()::observeDuration; + final var ddp = histogram.labelValues(labels); + return () -> ddp.startTimer()::observeDuration; } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedCounter.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedCounter.java new file mode 100644 index 00000000000..59a91d3f1c1 --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedCounter.java @@ -0,0 +1,73 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import static org.hyperledger.besu.metrics.prometheus.PrometheusCollector.getLabelValues; + +import org.hyperledger.besu.metrics.Observation; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +import java.util.List; + +import io.prometheus.metrics.core.metrics.CounterWithCallback; +import io.prometheus.metrics.model.registry.Collector; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; + +/** + * A Prometheus supplied counter collector. A supplied counter collector is one which actual value + * is kept outside the metric system, for example in an external library or to calculate the value + * only on demand when a metric scrape occurs. + */ +class PrometheusSuppliedCounter extends AbstractPrometheusSuppliedValueCollector { + + public PrometheusSuppliedCounter( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + super(category, name, help, labelNames); + } + + @Override + protected Collector createCollector(final String help, final String... labelNames) { + return CounterWithCallback.builder() + .name(this.prefixedName) + .help(help) + .labelNames(labelNames) + .callback(this::callback) + .build(); + } + + private void callback(final CounterWithCallback.Callback callback) { + labelledCallbackData + .values() + .forEach( + callbackData -> + callback.call( + callbackData.valueSupplier().getAsDouble(), callbackData.labelValues())); + } + + @Override + protected Observation convertToObservation(final DataPointSnapshot sample) { + final List labelValues = getLabelValues(sample.getLabels()); + + return new Observation( + category, + name, + ((CounterSnapshot.CounterDataPointSnapshot) sample).getValue(), + labelValues); + } +} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedGauge.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedGauge.java new file mode 100644 index 00000000000..1de04a5697d --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedGauge.java @@ -0,0 +1,73 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import static org.hyperledger.besu.metrics.prometheus.PrometheusCollector.getLabelValues; + +import org.hyperledger.besu.metrics.Observation; +import org.hyperledger.besu.plugin.services.metrics.LabelledGauge; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +import java.util.List; + +import io.prometheus.metrics.core.metrics.GaugeWithCallback; +import io.prometheus.metrics.model.registry.Collector; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; + +/** + * A Prometheus supplied gauge collector. A supplied gauge collector is one which actual value is + * kept outside the metric system, for example in an external library or to calculate the value only + * on demand when a metric scrape occurs. + */ +@SuppressWarnings("removal") +class PrometheusSuppliedGauge extends AbstractPrometheusSuppliedValueCollector + implements LabelledGauge { + + public PrometheusSuppliedGauge( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + super(category, name, help, labelNames); + } + + @Override + protected Collector createCollector(final String help, final String... labelNames) { + return GaugeWithCallback.builder() + .name(this.prefixedName) + .help(help) + .labelNames(labelNames) + .callback(this::callback) + .build(); + } + + private void callback(final GaugeWithCallback.Callback callback) { + labelledCallbackData + .values() + .forEach( + callbackData -> + callback.call( + callbackData.valueSupplier().getAsDouble(), callbackData.labelValues())); + } + + @Override + protected Observation convertToObservation(final DataPointSnapshot sample) { + final List labelValues = getLabelValues(sample.getLabels()); + + return new Observation( + category, name, ((GaugeSnapshot.GaugeDataPointSnapshot) sample).getValue(), labelValues); + } +} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedSummary.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedSummary.java new file mode 100644 index 00000000000..9ea975040c2 --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedSummary.java @@ -0,0 +1,83 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import org.hyperledger.besu.plugin.services.metrics.ExternalSummary; +import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedSummary; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; + +import io.prometheus.metrics.core.metrics.SummaryWithCallback; +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.Quantiles; + +/** + * A Prometheus supplied summary collector. A supplied summary collector is one which actual value + * is kept outside the metric system, for example in an external library or to calculate the value + * only on demand when a metric scrape occurs. + */ +class PrometheusSuppliedSummary extends AbstractPrometheusSummary + implements LabelledSuppliedSummary { + /** Map label values with the collector callback data */ + protected final Map, CallbackData> labelledCallbackData = new ConcurrentHashMap<>(); + + public PrometheusSuppliedSummary( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + super(category, name); + this.collector = + SummaryWithCallback.builder() + .name(name) + .help(help) + .labelNames(labelNames) + .callback(this::callback) + .build(); + } + + private void callback(final SummaryWithCallback.Callback callback) { + labelledCallbackData + .values() + .forEach( + callbackData -> { + final var externalSummary = callbackData.summarySupplier().get(); + final var quantilesBuilder = Quantiles.builder(); + externalSummary.quantiles().stream() + .map(pq -> new Quantile(pq.quantile(), pq.value())) + .forEach(quantilesBuilder::quantile); + callback.call( + externalSummary.count(), externalSummary.sum(), quantilesBuilder.build()); + }); + } + + @Override + public synchronized void labels( + final Supplier summarySupplier, final String... labelValues) { + final var valueList = List.of(labelValues); + if (labelledCallbackData.containsKey(valueList)) { + throw new IllegalArgumentException( + String.format("A collector has already been created for label values %s", valueList)); + } + + labelledCallbackData.put(valueList, new CallbackData(summarySupplier, labelValues)); + } + + protected record CallbackData(Supplier summarySupplier, String[] labelValues) {} +} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedValueCollector.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedValueCollector.java deleted file mode 100644 index 47394ffed4d..00000000000 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSuppliedValueCollector.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright contributors to Besu. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.metrics.prometheus; - -import org.hyperledger.besu.plugin.services.metrics.LabelledGauge; -import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedMetric; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.DoubleSupplier; - -import io.prometheus.client.Collector; - -/** The Prometheus supplied value collector. */ -@SuppressWarnings("removal") // remove when deprecated LabelledGauge is removed -public class PrometheusSuppliedValueCollector extends Collector - implements LabelledSuppliedMetric, LabelledGauge { - private final Type type; - private final String metricName; - private final String help; - private final List labelNames; - private final Map, DoubleSupplier> observationsMap = new ConcurrentHashMap<>(); - - /** - * Instantiates a new Prometheus supplied value collector. - * - * @param type the type of the collector - * @param metricName the metric name - * @param help the help - * @param labelNames the label names - */ - public PrometheusSuppliedValueCollector( - final Type type, final String metricName, final String help, final List labelNames) { - this.type = type; - this.metricName = metricName; - this.help = help; - this.labelNames = labelNames; - } - - @Override - public synchronized void labels(final DoubleSupplier valueSupplier, final String... labelValues) { - validateLabelsCardinality(labelValues); - if (observationsMap.putIfAbsent(List.of(labelValues), valueSupplier) != null) { - final String labelValuesString = String.join(",", labelValues); - throw new IllegalArgumentException( - String.format("A gauge has already been created for label values %s", labelValuesString)); - } - } - - @Override - public List collect() { - final List samples = new ArrayList<>(); - observationsMap.forEach( - (labels, valueSupplier) -> - samples.add( - new MetricFamilySamples.Sample( - metricName, labelNames, labels, valueSupplier.getAsDouble()))); - return List.of(new MetricFamilySamples(metricName, type, help, samples)); - } - - private void validateLabelsCardinality(final String... labelValues) { - if (labelValues.length != labelNames.size()) { - throw new IllegalArgumentException( - "Label values and label names must be the same cardinality"); - } - } -} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusTimer.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusTimer.java index ad50ab7149b..ccbe9c1b699 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusTimer.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusTimer.java @@ -15,21 +15,37 @@ package org.hyperledger.besu.metrics.prometheus; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; import org.hyperledger.besu.plugin.services.metrics.OperationTimer; -import io.prometheus.client.Summary; +import java.util.Map; -class PrometheusTimer implements LabelledMetric { +import io.prometheus.metrics.core.datapoints.DistributionDataPoint; +import io.prometheus.metrics.core.metrics.Summary; - private final Summary summary; +/** + * An implementation of Besu timer backed by a Prometheus summary. The summary provides a total + * count of durations and a sum of all observed durations, it calculates configurable quantiles over + * a sliding time window. + */ +class PrometheusTimer extends AbstractPrometheusSummary implements LabelledMetric { - public PrometheusTimer(final Summary summary) { - this.summary = summary; + public PrometheusTimer( + final MetricCategory category, + final String name, + final String help, + final Map quantiles, + final String... labelNames) { + super(category, name); + final var summaryBuilder = + Summary.builder().name(this.prefixedName).help(help).labelNames(labelNames); + quantiles.forEach(summaryBuilder::quantile); + this.collector = summaryBuilder.build(); } @Override public OperationTimer labels(final String... labels) { - final Summary.Child metric = summary.labels(labels); + final DistributionDataPoint metric = ((Summary) collector).labelValues(labels); return () -> metric.startTimer()::observeDuration; } } diff --git a/metrics/core/src/test-support/java/org/hyperledger/besu/metrics/StubMetricsSystem.java b/metrics/core/src/test-support/java/org/hyperledger/besu/metrics/StubMetricsSystem.java index 6b28ce4d363..9a4668b3c0d 100644 --- a/metrics/core/src/test-support/java/org/hyperledger/besu/metrics/StubMetricsSystem.java +++ b/metrics/core/src/test-support/java/org/hyperledger/besu/metrics/StubMetricsSystem.java @@ -18,10 +18,10 @@ import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; -import org.hyperledger.besu.plugin.services.metrics.ExternalSummary; import org.hyperledger.besu.plugin.services.metrics.Histogram; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedMetric; +import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedSummary; import org.hyperledger.besu.plugin.services.metrics.MetricCategory; import org.hyperledger.besu.plugin.services.metrics.OperationTimer; @@ -31,7 +31,6 @@ import java.util.Map; import java.util.Set; import java.util.function.DoubleSupplier; -import java.util.function.Supplier; import java.util.stream.Stream; import com.google.common.cache.Cache; @@ -99,11 +98,13 @@ public LabelledMetric createSimpleLabelledTimer( } @Override - public void trackExternalSummary( + public LabelledSuppliedSummary createLabelledSuppliedSummary( final MetricCategory category, final String name, final String help, - final Supplier summarySupplier) {} + final String... labelNames) { + return NoOpMetricsSystem.getLabelledSuppliedSummary(labelNames.length); + } @Override public void createGauge( @@ -114,10 +115,6 @@ public void createGauge( gauges.put(name, valueSupplier); } - @Override - public void createGuavaCacheCollector( - final MetricCategory category, final String name, final Cache cache) {} - @Override public LabelledMetric createLabelledHistogram( final MetricCategory category, @@ -125,9 +122,13 @@ public LabelledMetric createLabelledHistogram( final String help, final double[] buckets, final String... labelNames) { - return null; + return NoOpMetricsSystem.getHistogramLabelledMetric(labelNames.length); } + @Override + public void createGuavaCacheCollector( + final MetricCategory category, final String name, final Cache cache) {} + public double getGaugeValue(final String name) { final DoubleSupplier gauge = gauges.get(name); if (gauge == null) { diff --git a/metrics/core/src/test/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryMetricsSystemTest.java b/metrics/core/src/test/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryMetricsSystemTest.java index 8c6dd8261d5..5324d8cf3f9 100644 --- a/metrics/core/src/test/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryMetricsSystemTest.java +++ b/metrics/core/src/test/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryMetricsSystemTest.java @@ -50,9 +50,9 @@ public class OpenTelemetryMetricsSystemTest { private static final Comparator IGNORE_VALUES = - Comparator.comparing(observation -> observation.getCategory().getName()) - .thenComparing(Observation::getMetricName) - .thenComparing((o1, o2) -> o1.getLabels().equals(o2.getLabels()) ? 0 : 1); + Comparator.comparing(observation -> observation.category().getName()) + .thenComparing(Observation::metricName) + .thenComparing((o1, o2) -> o1.labels().equals(o2.labels()) ? 0 : 1); @BeforeEach public void resetGlobalOpenTelemetry() { @@ -266,7 +266,7 @@ public void shouldOnlyObserveEnabledMetrics() throws InterruptedException { final LabelledMetric counterN = localMetricSystem.createLabelledCounter( NETWORK, "ABC", "Not that kind of network", "show"); - assertThat(counterN).isSameAs(NoOpMetricsSystem.NO_OP_LABELLED_1_COUNTER); + assertThat(counterN).isInstanceOf(NoOpMetricsSystem.LabelCountingNoOpMetric.class); counterN.labels("show").inc(); assertThat(localMetricSystem.streamObservations()).isEmpty(); @@ -274,7 +274,7 @@ public void shouldOnlyObserveEnabledMetrics() throws InterruptedException { // do a category we are watching final LabelledMetric counterR = localMetricSystem.createLabelledCounter(RPC, "name", "Not useful", "method"); - assertThat(counterR).isNotSameAs(NoOpMetricsSystem.NO_OP_LABELLED_1_COUNTER); + assertThat(counterR).isNotInstanceOf(NoOpMetricsSystem.LabelCountingNoOpMetric.class); counterR.labels("op").inc(); assertThat(getObservation(localMetricSystem)) diff --git a/metrics/core/src/test/java/org/hyperledger/besu/metrics/prometheus/MetricsHttpServiceTest.java b/metrics/core/src/test/java/org/hyperledger/besu/metrics/prometheus/MetricsHttpServiceTest.java index 064dabfe331..b9bf700929a 100644 --- a/metrics/core/src/test/java/org/hyperledger/besu/metrics/prometheus/MetricsHttpServiceTest.java +++ b/metrics/core/src/test/java/org/hyperledger/besu/metrics/prometheus/MetricsHttpServiceTest.java @@ -24,43 +24,50 @@ import java.util.Properties; import io.opentelemetry.api.GlobalOpenTelemetry; -import io.prometheus.client.exporter.common.TextFormat; -import io.vertx.core.Vertx; +import io.prometheus.metrics.expositionformats.PrometheusTextFormatWriter; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; public class MetricsHttpServiceTest { - private static final Vertx vertx = Vertx.vertx(); - - private static MetricsHttpService service; - private static OkHttpClient client; - private static String baseUrl; - - @BeforeAll - public static void initServerAndClient() { - service = createMetricsHttpService(); - service.start().join(); + private PrometheusMetricsSystem metricsSystem; + private MetricsHttpService service; + private OkHttpClient client; + private String baseUrl; + + private void initServerAndClient( + final MetricsConfiguration metricsConfiguration, final boolean start) { + metricsSystem = (PrometheusMetricsSystem) MetricsSystemFactory.create(metricsConfiguration); + service = createMetricsHttpService(metricsConfiguration, metricsSystem); + if (start) { + service.start().join(); + } - // Build an OkHttp client. client = new OkHttpClient(); baseUrl = urlForSocketAddress("http", service.socketAddress()); } - private static MetricsHttpService createMetricsHttpService(final MetricsConfiguration config) { - GlobalOpenTelemetry.resetForTest(); - return new MetricsHttpService(vertx, config, MetricsSystemFactory.create(config)); + private void initServerAndClient(final boolean start) { + initServerAndClient(createMetricsConfig(), start); + } + + private void initServerAndClient() { + initServerAndClient(createMetricsConfig(), true); } - private static MetricsHttpService createMetricsHttpService() { + @AfterEach + public void stopServer() { + metricsSystem.shutdown(); + service.stop(); + } + + private MetricsHttpService createMetricsHttpService( + final MetricsConfiguration config, final PrometheusMetricsSystem metricsSystem) { GlobalOpenTelemetry.resetForTest(); - final MetricsConfiguration metricsConfiguration = createMetricsConfig(); - return new MetricsHttpService( - vertx, metricsConfiguration, MetricsSystemFactory.create(metricsConfiguration)); + return new MetricsHttpService(config, metricsSystem); } private static MetricsConfiguration createMetricsConfig() { @@ -71,15 +78,9 @@ private static MetricsConfiguration.Builder createMetricsConfigBuilder() { return MetricsConfiguration.builder().enabled(true).port(0).hostsAllowlist(singletonList("*")); } - /** Tears down the HTTP server. */ - @AfterAll - public static void shutdownServer() { - service.stop().join(); - vertx.close(); - } - @Test public void invalidCallToStart() { + initServerAndClient(); service .start() .whenComplete( @@ -88,6 +89,7 @@ public void invalidCallToStart() { @Test public void http404() throws Exception { + initServerAndClient(); try (final Response resp = client.newCall(buildGetRequest("/foo")).execute()) { assertThat(resp.code()).isEqualTo(404); } @@ -95,13 +97,15 @@ public void http404() throws Exception { @Test public void handleEmptyRequest() throws Exception { + initServerAndClient(); try (final Response resp = client.newCall(buildGetRequest("")).execute()) { - assertThat(resp.code()).isEqualTo(201); + assertThat(resp.code()).isEqualTo(200); } } @Test public void getSocketAddressWhenActive() { + initServerAndClient(); final InetSocketAddress socketAddress = service.socketAddress(); assertThat("127.0.0.1").isEqualTo(socketAddress.getAddress().getHostAddress()); assertThat(socketAddress.getPort() > 0).isTrue(); @@ -109,7 +113,7 @@ public void getSocketAddressWhenActive() { @Test public void getSocketAddressWhenStoppedIsEmpty() { - final MetricsHttpService service = createMetricsHttpService(); + initServerAndClient(false); final InetSocketAddress socketAddress = service.socketAddress(); assertThat("0.0.0.0").isEqualTo(socketAddress.getAddress().getHostAddress()); @@ -119,9 +123,7 @@ public void getSocketAddressWhenStoppedIsEmpty() { @Test public void getSocketAddressWhenBindingToAllInterfaces() { - final MetricsConfiguration config = createMetricsConfigBuilder().host("0.0.0.0").build(); - final MetricsHttpService service = createMetricsHttpService(config); - service.start().join(); + initServerAndClient(createMetricsConfigBuilder().host("0.0.0.0").build(), true); try { final InetSocketAddress socketAddress = service.socketAddress(); @@ -134,6 +136,7 @@ public void getSocketAddressWhenBindingToAllInterfaces() { @Test public void metricsArePresent() throws Exception { + initServerAndClient(); final Request metricsRequest = new Request.Builder().url(baseUrl + "/metrics").build(); try (final Response resp = client.newCall(metricsRequest).execute()) { assertThat(resp.code()).isEqualTo(200); @@ -148,6 +151,7 @@ public void metricsArePresent() throws Exception { @Test public void metricsArePresentWhenFiltered() throws Exception { + initServerAndClient(); final Request metricsRequest = new Request.Builder().url(baseUrl + "/metrics?name[]=jvm_threads_deadlocked").build(); try (final Response resp = client.newCall(metricsRequest).execute()) { @@ -163,6 +167,7 @@ public void metricsArePresentWhenFiltered() throws Exception { @Test public void metricsAreAbsentWhenFiltered() throws Exception { + initServerAndClient(); final Request metricsRequest = new Request.Builder().url(baseUrl + "/metrics?name[]=does_not_exist").build(); try (final Response resp = client.newCall(metricsRequest).execute()) { @@ -179,6 +184,7 @@ public void metricsAreAbsentWhenFiltered() throws Exception { @Test // There is only one available representation so content negotiation should not be used public void acceptHeaderIgnored() throws Exception { + initServerAndClient(); final Request metricsRequest = new Request.Builder().addHeader("Accept", "text/xml").url(baseUrl + "/metrics").build(); try (final Response resp = client.newCall(metricsRequest).execute()) { @@ -189,7 +195,7 @@ public void acceptHeaderIgnored() throws Exception { // We should have JVM metrics already loaded, verify a simple key. assertThat(props).containsKey("jvm_threads_deadlocked"); - assertThat(resp.header("Content-Type")).contains(TextFormat.CONTENT_TYPE_004); + assertThat(resp.header("Content-Type")).contains(PrometheusTextFormatWriter.CONTENT_TYPE); } } diff --git a/metrics/core/src/test/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystemTest.java b/metrics/core/src/test/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystemTest.java index ba875ab79b1..60b125fe507 100644 --- a/metrics/core/src/test/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystemTest.java +++ b/metrics/core/src/test/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystemTest.java @@ -20,6 +20,7 @@ import static java.util.function.Predicate.not; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hyperledger.besu.metrics.BesuMetricCategory.BLOCKCHAIN; import static org.hyperledger.besu.metrics.BesuMetricCategory.DEFAULT_METRIC_CATEGORIES; import static org.hyperledger.besu.metrics.BesuMetricCategory.NETWORK; import static org.hyperledger.besu.metrics.BesuMetricCategory.PEERS; @@ -33,38 +34,38 @@ import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; +import org.hyperledger.besu.plugin.services.metrics.Histogram; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedMetric; import org.hyperledger.besu.plugin.services.metrics.OperationTimer; import java.util.Collections; -import java.util.Comparator; import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.stream.IntStream; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.google.common.collect.ImmutableSet; import io.opentelemetry.api.GlobalOpenTelemetry; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class PrometheusMetricsSystemTest { - private static final Comparator IGNORE_VALUES = - Comparator.comparing(observation -> observation.getCategory().getName()) - .thenComparing(Observation::getMetricName) - .thenComparing((o1, o2) -> o1.getLabels().equals(o2.getLabels()) ? 0 : 1); - private static final Comparator WITH_VALUES = - Comparator.comparing(observation -> observation.getCategory().getName()) - .thenComparing(Observation::getMetricName) - .thenComparing((o1, o2) -> o1.getLabels().equals(o2.getLabels()) ? 0 : 1) - .thenComparing((o1, o2) -> o1.getValue().equals(o2.getValue()) ? 0 : 1); + private PrometheusMetricsSystem metricsSystem; @BeforeEach - public void resetGlobalOpenTelemetry() { + public void setUp() { + metricsSystem = new PrometheusMetricsSystem(DEFAULT_METRIC_CATEGORIES, true); GlobalOpenTelemetry.resetForTest(); } - private final ObservableMetricsSystem metricsSystem = - new PrometheusMetricsSystem(DEFAULT_METRIC_CATEGORIES, true); + @AfterEach + public void tearDown() { + metricsSystem.shutdown(); + } @Test public void shouldCreateObservationFromCounter() { @@ -72,17 +73,11 @@ public void shouldCreateObservationFromCounter() { counter.inc(); assertThat(metricsSystem.streamObservations()) - .usingElementComparator(this::compareCounters) - .containsExactlyInAnyOrder( - new Observation(PEERS, "connected", 1.0, emptyList()), - new Observation(PEERS, "connected", null, List.of("created"))); + .containsExactlyInAnyOrder(new Observation(PEERS, "connected", 1.0, emptyList())); counter.inc(); assertThat(metricsSystem.streamObservations()) - .usingElementComparator(this::compareCounters) - .containsExactly( - new Observation(PEERS, "connected", 2.0, emptyList()), - new Observation(PEERS, "connected", null, List.of("created"))); + .containsExactly(new Observation(PEERS, "connected", 2.0, emptyList())); } @Test @@ -95,17 +90,11 @@ public void shouldHandleDuplicateCounterCreation() { counter1.labels().inc(); assertThat(metricsSystem.streamObservations()) - .usingElementComparator(this::compareCounters) - .containsExactly( - new Observation(PEERS, "connected", 1.0, emptyList()), - new Observation(PEERS, "connected", null, List.of("created"))); + .containsExactly(new Observation(PEERS, "connected", 1.0, emptyList())); counter2.labels().inc(); assertThat(metricsSystem.streamObservations()) - .usingElementComparator(this::compareCounters) - .containsExactly( - new Observation(PEERS, "connected", 2.0, emptyList()), - new Observation(PEERS, "connected", null, List.of("created"))); + .containsExactly(new Observation(PEERS, "connected", 2.0, emptyList())); } @Test @@ -119,12 +108,9 @@ public void shouldCreateSeparateObservationsForEachCounterLabelValue() { counter.labels("value1").inc(); assertThat(metricsSystem.streamObservations()) - .usingElementComparator(this::compareCounters) .containsExactlyInAnyOrder( new Observation(PEERS, "connected_total", 2.0, singletonList("value1")), - new Observation(PEERS, "connected_total", 1.0, singletonList("value2")), - new Observation(PEERS, "connected_total", null, List.of("value1", "created")), - new Observation(PEERS, "connected_total", null, List.of("value2", "created"))); + new Observation(PEERS, "connected_total", 1.0, singletonList("value2"))); } @Test @@ -160,18 +146,12 @@ public void shouldIncrementCounterBySpecifiedAmount() { counter.inc(5); assertThat(metricsSystem.streamObservations()) - .usingElementComparator(this::compareCounters) - .containsExactly( - new Observation(PEERS, "connected", 5.0, emptyList()), - new Observation(PEERS, "connected", null, List.of("created"))); + .containsExactly(new Observation(PEERS, "connected", 5.0, emptyList())); counter.inc(6); assertThat(metricsSystem.streamObservations()) .usingDefaultElementComparator() - .usingElementComparator(this::compareCounters) - .containsExactly( - new Observation(PEERS, "connected", 11.0, emptyList()), - new Observation(PEERS, "connected", null, List.of("created"))); + .containsExactly(new Observation(PEERS, "connected", 11.0, emptyList())); } @Test @@ -179,20 +159,34 @@ public void shouldCreateObservationsFromTimer() { final OperationTimer timer = metricsSystem.createTimer(RPC, "request", "Some help"); final OperationTimer.TimingContext context = timer.startTimer(); - context.stopTimer(); + final var expected = context.stopTimer(); + + assertThat(metricsSystem.streamObservations()) + .containsExactlyInAnyOrder( + new Observation(RPC, "request", expected, asList("quantile", "0.2")), + new Observation(RPC, "request", expected, asList("quantile", "0.5")), + new Observation(RPC, "request", expected, asList("quantile", "0.8")), + new Observation(RPC, "request", expected, asList("quantile", "0.95")), + new Observation(RPC, "request", expected, asList("quantile", "0.99")), + new Observation(RPC, "request", expected, asList("quantile", "1.0")), + new Observation(RPC, "request", expected, singletonList("sum")), + new Observation(RPC, "request", 1L, singletonList("count"))); + } + + @Test + public void shouldCreateObservationsFromHistogram() { + final Histogram histogram = + metricsSystem.createHistogram(RPC, "request", "Some help", new double[] {5.0, 9.0}); + + IntStream.rangeClosed(1, 10).forEach(histogram::observe); assertThat(metricsSystem.streamObservations()) - .usingElementComparator(IGNORE_VALUES) .containsExactlyInAnyOrder( - new Observation(RPC, "request", null, asList("quantile", "0.2")), - new Observation(RPC, "request", null, asList("quantile", "0.5")), - new Observation(RPC, "request", null, asList("quantile", "0.8")), - new Observation(RPC, "request", null, asList("quantile", "0.95")), - new Observation(RPC, "request", null, asList("quantile", "0.99")), - new Observation(RPC, "request", null, asList("quantile", "1.0")), - new Observation(RPC, "request", null, singletonList("sum")), - new Observation(RPC, "request", null, singletonList("count")), - new Observation(RPC, "request", null, singletonList("created"))); + new Observation(RPC, "request", 5L, asList("bucket", "5.0")), + new Observation(RPC, "request", 4L, asList("bucket", "9.0")), + new Observation(RPC, "request", 1L, asList("bucket", "Infinity")), + new Observation(RPC, "request", 55.0, singletonList("sum")), + new Observation(RPC, "request", 10L, singletonList("count"))); } @Test @@ -209,21 +203,19 @@ public void shouldCreateObservationsFromTimerWithLabels() { final LabelledMetric timer = metricsSystem.createLabelledTimer(RPC, "request", "Some help", "methodName"); - //noinspection EmptyTryBlock - try (final OperationTimer.TimingContext ignored = timer.labels("method").startTimer()) {} + final OperationTimer.TimingContext context = timer.labels("method").startTimer(); + final double expected = context.stopTimer(); assertThat(metricsSystem.streamObservations()) - .usingElementComparator(IGNORE_VALUES) // We don't know how long it will actually take. .containsExactlyInAnyOrder( - new Observation(RPC, "request", null, asList("method", "quantile", "0.2")), - new Observation(RPC, "request", null, asList("method", "quantile", "0.5")), - new Observation(RPC, "request", null, asList("method", "quantile", "0.8")), - new Observation(RPC, "request", null, asList("method", "quantile", "0.95")), - new Observation(RPC, "request", null, asList("method", "quantile", "0.99")), - new Observation(RPC, "request", null, asList("method", "quantile", "1.0")), - new Observation(RPC, "request", null, asList("method", "sum")), - new Observation(RPC, "request", null, asList("method", "count")), - new Observation(RPC, "request", null, asList("method", "created"))); + new Observation(RPC, "request", expected, asList("method", "quantile", "0.2")), + new Observation(RPC, "request", expected, asList("method", "quantile", "0.5")), + new Observation(RPC, "request", expected, asList("method", "quantile", "0.8")), + new Observation(RPC, "request", expected, asList("method", "quantile", "0.95")), + new Observation(RPC, "request", expected, asList("method", "quantile", "0.99")), + new Observation(RPC, "request", expected, asList("method", "quantile", "1.0")), + new Observation(RPC, "request", expected, asList("method", "sum")), + new Observation(RPC, "request", 1L, asList("method", "count"))); } @Test @@ -270,7 +262,7 @@ public void shouldOnlyObserveEnabledMetrics() { // do a category we are not watching final LabelledMetric counterN = localMetricSystem.createLabelledCounter(NETWORK, "ABC", "Not that kind of network", "show"); - assertThat(counterN).isSameAs(NoOpMetricsSystem.NO_OP_LABELLED_1_COUNTER); + assertThat(counterN).isInstanceOf(NoOpMetricsSystem.LabelCountingNoOpMetric.class); counterN.labels("show").inc(); assertThat(localMetricSystem.streamObservations()).isEmpty(); @@ -278,7 +270,7 @@ public void shouldOnlyObserveEnabledMetrics() { // do a category we are watching final LabelledMetric counterR = localMetricSystem.createLabelledCounter(RPC, "name", "Not useful", "method"); - assertThat(counterR).isNotSameAs(NoOpMetricsSystem.NO_OP_LABELLED_1_COUNTER); + assertThat(counterR).isNotInstanceOf(NoOpMetricsSystem.LabelCountingNoOpMetric.class); counterR.labels("op").inc(); assertThat(localMetricSystem.streamObservations()) @@ -314,17 +306,28 @@ public void returnsNoOpMetricsWhenPushEnabled() { assertThat(localMetricSystem).isInstanceOf(PrometheusMetricsSystem.class); } + @Test + public void shouldCreateObservationFromGuavaCache() throws ExecutionException { + final Cache guavaCache = + CacheBuilder.newBuilder().maximumSize(1).recordStats().build(); + metricsSystem.createGuavaCacheCollector(BLOCKCHAIN, "test", guavaCache); + + guavaCache.put("a", "b"); + guavaCache.get("a", () -> "b"); + guavaCache.get("z", () -> "x"); + + assertThat(metricsSystem.streamObservations()) + .containsExactlyInAnyOrder( + new Observation(BLOCKCHAIN, "guava_cache_size", 1.0, List.of("test")), + new Observation(BLOCKCHAIN, "guava_cache_requests", 2.0, List.of("test")), + new Observation(BLOCKCHAIN, "guava_cache_hit", 1.0, List.of("test")), + new Observation(BLOCKCHAIN, "guava_cache_miss", 1.0, List.of("test")), + new Observation(BLOCKCHAIN, "guava_cache_eviction", 1.0, List.of("test"))); + } + private boolean isCreatedSample(final Observation obs) { // Simple client 0.10.0 add a _created sample to every counter, histogram and summary, that we // may want to ignore - return obs.getLabels().contains("created"); - } - - private int compareCounters(final Observation obs1, final Observation obs2) { - // for created samples ignore values - if (obs1.getLabels().contains("created") && obs2.getLabels().contains("created")) { - return IGNORE_VALUES.compare(obs1, obs2); - } - return WITH_VALUES.compare(obs1, obs2); + return obs.labels().contains("created"); } } diff --git a/metrics/rocksdb/src/main/java/org/hyperledger/besu/metrics/rocksdb/RocksDBStats.java b/metrics/rocksdb/src/main/java/org/hyperledger/besu/metrics/rocksdb/RocksDBStats.java index c3c5fef2c11..2f101d5fe7a 100644 --- a/metrics/rocksdb/src/main/java/org/hyperledger/besu/metrics/rocksdb/RocksDBStats.java +++ b/metrics/rocksdb/src/main/java/org/hyperledger/besu/metrics/rocksdb/RocksDBStats.java @@ -107,7 +107,6 @@ public class RocksDBStats { TickerType.NUMBER_SUPERVERSION_CLEANUPS, TickerType.NUMBER_BLOCK_COMPRESSED, TickerType.NUMBER_BLOCK_DECOMPRESSED, - TickerType.NUMBER_BLOCK_NOT_COMPRESSED, TickerType.MERGE_OPERATION_TOTAL_TIME, TickerType.FILTER_OPERATION_TOTAL_TIME, TickerType.ROW_CACHE_HIT, @@ -143,8 +142,6 @@ public class RocksDBStats { HistogramType.BYTES_PER_READ, HistogramType.BYTES_PER_WRITE, HistogramType.BYTES_PER_MULTIGET, - HistogramType.BYTES_COMPRESSED, - HistogramType.BYTES_DECOMPRESSED, HistogramType.COMPRESSION_TIMES_NANOS, HistogramType.DECOMPRESSION_TIMES_NANOS, HistogramType.READ_NUM_MERGE_OPERANDS, @@ -174,7 +171,7 @@ public static void registerRocksDBMetrics( for (final var histogramType : HISTOGRAM_TYPES) { - metricsSystem.trackExternalSummary( + metricsSystem.createSummary( KVSTORE_ROCKSDB_STATS, KVSTORE_ROCKSDB_STATS.getName() + "_" + histogramType.name().toLowerCase(Locale.ROOT), "RocksDB histogram for " + histogramType.name(), diff --git a/platform/build.gradle b/platform/build.gradle index a07f54b53f0..8889e298ff4 100644 --- a/platform/build.gradle +++ b/platform/build.gradle @@ -30,7 +30,7 @@ dependencies { api platform('io.grpc:grpc-bom:1.68.0') api platform('io.netty:netty-bom:4.1.115.Final') api platform('io.opentelemetry:opentelemetry-bom:1.43.0') - api platform('io.prometheus:simpleclient_bom:0.16.0') + api platform('io.prometheus:prometheus-metrics-bom:1.3.4') api platform('io.vertx:vertx-stack-depchain:4.5.10') api platform('org.apache.logging.log4j:log4j-bom:2.24.1') api platform('org.assertj:assertj-bom:3.26.3') @@ -163,7 +163,7 @@ dependencies { api 'org.owasp.encoder:encoder:1.3.1' - api 'org.rocksdb:rocksdbjni:8.3.2' + api 'org.rocksdb:rocksdbjni:9.7.3' api 'org.springframework.security:spring-security-crypto:6.3.3' diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 8e0a1dea0c6..a3a5e07edd3 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -71,7 +71,7 @@ Calculated : ${currentHash} tasks.register('checkAPIChanges', FileStateChecker) { description = "Checks that the API for the Plugin-API project does not change without deliberate thought" files = sourceSets.main.allJava.files - knownHash = 'vyZuTDNqHnLzOZ4NAPirgEavpkk5A85Q5GeywJ1LI+I=' + knownHash = 'f6fi+lsYVZtFjmGOyiMPPCfNDie4SIPpj6HVgXRxF8Q=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuPlugin.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuPlugin.java index b05fbf83c09..d4f2a08f2c2 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuPlugin.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuPlugin.java @@ -48,7 +48,8 @@ default Optional getName() { * * @param context the context that provides access to Besu services. */ - void register(ServiceManager context); + @SuppressWarnings("removal") + void register(BesuContext context); /** * Called once when besu has loaded configuration but before external services have been started diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/MetricsSystem.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/MetricsSystem.java index 73fc50c2757..0516cccf073 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/MetricsSystem.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/MetricsSystem.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.plugin.services.metrics.LabelledGauge; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedMetric; +import org.hyperledger.besu.plugin.services.metrics.LabelledSuppliedSummary; import org.hyperledger.besu.plugin.services.metrics.MetricCategory; import org.hyperledger.besu.plugin.services.metrics.OperationTimer; @@ -185,7 +186,13 @@ LabelledMetric createSimpleLabelledTimer( * @param help A human readable description of the metric. * @param valueSupplier A supplier for the double value to be presented. */ - void createGauge(MetricCategory category, String name, String help, DoubleSupplier valueSupplier); + default void createGauge( + final MetricCategory category, + final String name, + final String help, + final DoubleSupplier valueSupplier) { + createLabelledSuppliedGauge(category, name, help).labels(valueSupplier); + } /** * Creates a gauge for displaying integer values. @@ -220,7 +227,48 @@ default void createLongGauge( } /** - * Track a summary that is computed externally to this metric system. Useful when existing + * Creates a histogram with assigned labels + * + * @param category The {@link MetricCategory} this histogram is assigned to. + * @param name A name for this metric. + * @param help A human-readable description of the metric. + * @param buckets An array of buckets to assign to the histogram + * @param labelNames An array of labels to assign to the histogram. + * @return The labelled histogram. + */ + LabelledMetric createLabelledHistogram( + MetricCategory category, String name, String help, double[] buckets, String... labelNames); + + /** + * Creates a histogram + * + * @param category The {@link MetricCategory} this histogram is assigned to. + * @param name A name for this metric. + * @param help A human-readable description of the metric. + * @param buckets An array of buckets to assign to the histogram + * @return The labelled histogram. + */ + default Histogram createHistogram( + final MetricCategory category, final String name, final String help, final double[] buckets) { + return createLabelledHistogram(category, name, help, buckets).labels(); + } + + /** + * Create a summary with assigned labels, that is computed externally to this metric system. + * Useful when existing libraries calculate the summary data on their own, and we want to export + * that summary via the configured metric system. A notable example are RocksDB statistics. + * + * @param category The {@link MetricCategory} this external summary is assigned to. + * @param name A name for the metric. + * @param help A human readable description of the metric. + * @param labelNames An array of labels to assign to the supplier summary. + * @return The created labelled supplied summary + */ + LabelledSuppliedSummary createLabelledSuppliedSummary( + MetricCategory category, String name, String help, String... labelNames); + + /** + * Create a summary that is computed externally to this metric system. Useful when existing * libraries calculate the summary data on their own, and we want to export that summary via the * configured metric system. A notable example are RocksDB statistics. * @@ -229,8 +277,13 @@ default void createLongGauge( * @param help A human readable description of the metric. * @param summarySupplier A supplier to retrieve the summary data when needed. */ - void trackExternalSummary( - MetricCategory category, String name, String help, Supplier summarySupplier); + default void createSummary( + final MetricCategory category, + final String name, + final String help, + final Supplier summarySupplier) { + createLabelledSuppliedSummary(category, name, help).labels(summarySupplier); + } /** * Collect metrics from Guava cache. @@ -259,17 +312,4 @@ default boolean isCategoryEnabled(final MetricCategory category) { .map(MetricCategory::getName) .anyMatch(category.getName()::equals); } - - /** - * Creates a histogram with assigned labels - * - * @param category The {@link MetricCategory} this histogram is assigned to. - * @param name A name for this metric. - * @param help A human-readable description of the metric. - * @param buckets An array of buckets to assign to the histogram - * @param labelNames An array of labels to assign to the histogram. - * @return The labelled histogram. - */ - LabelledMetric createLabelledHistogram( - MetricCategory category, String name, String help, double[] buckets, String... labelNames); } diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/Histogram.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/Histogram.java index 5f252fdfd1a..2a63e9c7254 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/Histogram.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/Histogram.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledSuppliedSummary.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledSuppliedSummary.java new file mode 100644 index 00000000000..de4cf7f933c --- /dev/null +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledSuppliedSummary.java @@ -0,0 +1,28 @@ +/* + * 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.plugin.services.metrics; + +import java.util.function.Supplier; + +/** The interface Labelled supplied summary. */ +public interface LabelledSuppliedSummary { + /** + * Labels. + * + * @param summarySupplier the summary supplier + * @param labelValues the label values + */ + void labels(final Supplier summarySupplier, final String... labelValues); +} diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/mining/MiningService.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/mining/MiningService.java new file mode 100644 index 00000000000..396d011cb06 --- /dev/null +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/mining/MiningService.java @@ -0,0 +1,27 @@ +/* + * 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.plugin.services.mining; + +import org.hyperledger.besu.plugin.services.BesuService; + +/** The MiningService interface provides methods to start and stop the mining process. */ +public interface MiningService extends BesuService { + + /** Starts the mining process. */ + void start(); + + /** Stops the mining process. */ + void stop(); +} diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/sync/SynchronizationService.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/sync/SynchronizationService.java index ad9682429d0..1b1ea8bdfea 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/sync/SynchronizationService.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/sync/SynchronizationService.java @@ -59,4 +59,10 @@ public interface SynchronizationService extends BesuService { /** Disables the worldstate trie for update. */ void disableWorldStateTrie(); + + /** Stops the synchronizer. */ + void stop(); + + /** Starts the synchronizer. */ + void start(); } diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBPlugin.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBPlugin.java index 91e6e427bc3..0496bcb02b7 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBPlugin.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBPlugin.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.plugin.services.storage.rocksdb; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.PicoCLIOptions; @@ -59,7 +60,8 @@ public void addIgnorableSegmentIdentifier(final SegmentIdentifier ignorable) { } @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { LOG.debug("Registering plugin"); this.context = context; diff --git a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/InMemoryStoragePlugin.java b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/InMemoryStoragePlugin.java index 11e7656dfb7..ff691a2a68c 100644 --- a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/InMemoryStoragePlugin.java +++ b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/InMemoryStoragePlugin.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.services.kvstore; +import org.hyperledger.besu.plugin.BesuContext; import org.hyperledger.besu.plugin.BesuPlugin; import org.hyperledger.besu.plugin.ServiceManager; import org.hyperledger.besu.plugin.services.BesuConfiguration; @@ -44,7 +45,8 @@ public class InMemoryStoragePlugin implements BesuPlugin { public InMemoryStoragePlugin() {} @Override - public void register(final ServiceManager context) { + @SuppressWarnings("removal") + public void register(final BesuContext context) { LOG.debug("Registering plugin"); this.context = context;