From be8f4945b0772b035d10a2a07ada69c178acb7b6 Mon Sep 17 00:00:00 2001 From: Stefan Pingel <16143240+pinges@users.noreply.github.com> Date: Thu, 29 Aug 2024 00:30:56 +1000 Subject: [PATCH] Metrics for sync phases (#7390) * add metrics to measure the time for chain and world state sync Signed-off-by: stefan.pingel@consensys.net Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Co-authored-by: Simon Dudley Co-authored-by: Sally MacFarlane --- .../WorldStateDownloaderBenchmark.java | 4 +- .../eth/sync/DefaultSynchronizer.java | 23 ++++- .../eth/sync/PipelineChainDownloader.java | 9 +- .../CheckpointDownloaderFactory.java | 10 +- .../checkpointsync/CheckpointSyncActions.java | 7 +- .../CheckpointSyncChainDownloader.java | 7 +- .../eth/sync/fastsync/FastSyncActions.java | 7 +- .../fastsync/FastSyncChainDownloader.java | 7 +- .../eth/sync/fastsync/FastSyncDownloader.java | 10 +- .../worldstate/FastDownloaderFactory.java | 10 +- .../worldstate/FastWorldDownloadState.java | 9 +- .../worldstate/FastWorldStateDownloader.java | 9 +- .../fullsync/FullSyncChainDownloader.java | 7 +- .../eth/sync/fullsync/FullSyncDownloader.java | 7 +- .../sync/snapsync/SnapDownloaderFactory.java | 15 +-- .../eth/sync/snapsync/SnapSyncDownloader.java | 7 +- .../sync/snapsync/SnapWorldDownloadState.java | 89 +++++++++--------- .../snapsync/SnapWorldStateDownloader.java | 9 +- .../sync/worldstate/WorldDownloadState.java | 6 +- .../eth/sync/PipelineChainDownloaderTest.java | 5 +- .../CheckPointSyncChainDownloaderTest.java | 4 +- .../fastsync/FastDownloaderFactoryTest.java | 16 +++- .../fastsync/FastSyncChainDownloaderTest.java | 4 +- .../sync/fastsync/FastSyncDownloaderTest.java | 83 ++++++++++++----- .../FastWorldDownloadStateTest.java | 4 +- .../FastWorldStateDownloaderTest.java | 4 +- .../FullSyncChainDownloaderForkTest.java | 4 +- .../fullsync/FullSyncChainDownloaderTest.java | 4 +- ...DownloaderTotalTerminalDifficultyTest.java | 4 +- .../sync/fullsync/FullSyncDownloaderTest.java | 4 +- .../snapsync/SnapWorldDownloadStateTest.java | 4 +- .../besu/metrics/SyncDurationMetrics.java | 91 +++++++++++++++++++ .../besu/metrics/noop/NoOpMetricsSystem.java | 9 ++ .../opentelemetry/OpenTelemetrySystem.java | 9 ++ .../prometheus/PrometheusMetricsSystem.java | 22 +++++ .../prometheus/PrometheusSimpleTimer.java | 35 +++++++ .../besu/metrics/StubMetricsSystem.java | 9 ++ plugin-api/build.gradle | 2 +- .../besu/plugin/services/MetricsSystem.java | 28 ++++++ 39 files changed, 473 insertions(+), 124 deletions(-) create mode 100644 metrics/core/src/main/java/org/hyperledger/besu/metrics/SyncDurationMetrics.java create mode 100644 metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java diff --git a/ethereum/eth/src/jmh/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldStateDownloaderBenchmark.java b/ethereum/eth/src/jmh/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldStateDownloaderBenchmark.java index 04d4af81a94..079b6ba47fa 100644 --- a/ethereum/eth/src/jmh/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldStateDownloaderBenchmark.java +++ b/ethereum/eth/src/jmh/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldStateDownloaderBenchmark.java @@ -43,6 +43,7 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.ObservableMetricsSystem; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory; import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory; @@ -120,7 +121,8 @@ public void setUpUnchangedState() { syncConfig.getWorldStateMaxRequestsWithoutProgress(), syncConfig.getWorldStateMinMillisBeforeStalling(), Clock.fixed(Instant.ofEpochSecond(1000), ZoneOffset.UTC), - metricsSystem); + metricsSystem, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private Hash createExistingWorldState() { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java index a41ad1812b5..b7dc2adb160 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java @@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.data.SyncStatus; import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.plugin.services.BesuEvents.SyncStatusListener; @@ -67,6 +68,7 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi private final AtomicBoolean running = new AtomicBoolean(false); private final Optional blockPropagationManager; private final Supplier>> fastSyncFactory; + private final SyncDurationMetrics syncDurationMetrics; private Optional> fastSyncDownloader; private final Optional fullSyncDownloader; private final ProtocolContext protocolContext; @@ -118,6 +120,8 @@ public DefaultSynchronizer( metricsSystem, blockBroadcaster)); + syncDurationMetrics = new SyncDurationMetrics(metricsSystem); + this.fullSyncDownloader = terminationCondition.shouldStopDownload() ? Optional.empty() @@ -129,7 +133,8 @@ public DefaultSynchronizer( ethContext, syncState, metricsSystem, - terminationCondition)); + terminationCondition, + syncDurationMetrics)); if (SyncMode.FAST.equals(syncConfig.getSyncMode())) { this.fastSyncFactory = @@ -144,7 +149,8 @@ public DefaultSynchronizer( ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + syncDurationMetrics); } else if (syncConfig.getSyncMode() == SyncMode.CHECKPOINT) { this.fastSyncFactory = () -> @@ -159,7 +165,8 @@ public DefaultSynchronizer( ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + syncDurationMetrics); } else { this.fastSyncFactory = () -> @@ -174,7 +181,8 @@ public DefaultSynchronizer( ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + syncDurationMetrics); } // create a non-resync fast sync downloader: @@ -205,6 +213,9 @@ public TrailingPeerRequirements calculateTrailingPeerRequirements() { public CompletableFuture start() { if (running.compareAndSet(false, true)) { LOG.info("Starting synchronizer."); + + syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.TOTAL_SYNC_DURATION); + blockPropagationManager.ifPresent( manager -> { if (!manager.isRunning()) { @@ -390,6 +401,10 @@ private Void finalizeSync(final Void unused) { blockPropagationManager.ifPresent(BlockPropagationManager::stop); LOG.info("Stopping the pruner."); running.set(false); + + syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.FLAT_DB_HEAL); + syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.TOTAL_SYNC_DURATION); + return null; } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloader.java index bfec1435ce4..8f2ee1d48a0 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloader.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.eth.sync.tasks.exceptions.InvalidBlockException; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; @@ -51,6 +52,7 @@ public class PipelineChainDownloader implements ChainDownloader { private final AtomicBoolean cancelled = new AtomicBoolean(false); private final Counter pipelineCompleteCounter; private final Counter pipelineErrorCounter; + private final SyncDurationMetrics syncDurationMetrics; private Pipeline currentDownloadPipeline; public PipelineChainDownloader( @@ -58,11 +60,13 @@ public PipelineChainDownloader( final AbstractSyncTargetManager syncTargetManager, final DownloadPipelineFactory downloadPipelineFactory, final EthScheduler scheduler, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final SyncDurationMetrics syncDurationMetrics) { this.syncState = syncState; this.syncTargetManager = syncTargetManager; this.downloadPipelineFactory = downloadPipelineFactory; this.scheduler = scheduler; + this.syncDurationMetrics = syncDurationMetrics; final LabelledMetric labelledCounter = metricsSystem.createLabelledCounter( @@ -79,6 +83,9 @@ public CompletableFuture start() { if (!started.compareAndSet(false, true)) { throw new IllegalStateException("Cannot start a chain download twice"); } + + syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.CHAIN_DOWNLOAD_DURATION); + return performDownload(); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointDownloaderFactory.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointDownloaderFactory.java index 8668f2beffc..03df47e4407 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointDownloaderFactory.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointDownloaderFactory.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.trie.CompactEncoding; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -62,7 +63,8 @@ public static Optional> createCheckpointDownloader( final EthContext ethContext, final WorldStateStorageCoordinator worldStateStorageCoordinator, final SyncState syncState, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { final Path fastSyncDataDirectory = dataDirectory.resolve(FAST_SYNC_FOLDER); final FastSyncStateStorage fastSyncStateStorage = @@ -149,7 +151,8 @@ public static Optional> createCheckpointDownloader( syncConfig.getWorldStateMaxRequestsWithoutProgress(), syncConfig.getWorldStateMinMillisBeforeStalling(), clock, - metricsSystem); + metricsSystem, + syncDurationMetrics); final FastSyncDownloader fastSyncDownloader = new SnapSyncDownloader( fastSyncActions, @@ -158,7 +161,8 @@ public static Optional> createCheckpointDownloader( fastSyncStateStorage, snapTaskCollection, fastSyncDataDirectory, - snapSyncState); + snapSyncState, + syncDurationMetrics); syncState.setWorldStateDownloadStatus(snapWorldStateDownloader); return Optional.of(fastSyncDownloader); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncActions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncActions.java index bfe6a308a21..5096b74e24f 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncActions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncActions.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; public class CheckpointSyncActions extends FastSyncActions { @@ -48,7 +49,8 @@ public CheckpointSyncActions( } @Override - public ChainDownloader createChainDownloader(final FastSyncState currentState) { + public ChainDownloader createChainDownloader( + final FastSyncState currentState, final SyncDurationMetrics syncDurationMetrics) { return CheckpointSyncChainDownloader.create( syncConfig, worldStateStorageCoordinator, @@ -57,6 +59,7 @@ public ChainDownloader createChainDownloader(final FastSyncState currentState) { ethContext, syncState, metricsSystem, - currentState); + currentState, + syncDurationMetrics); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncChainDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncChainDownloader.java index aaafac5ac99..5450b9e5a49 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncChainDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncChainDownloader.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; public class CheckpointSyncChainDownloader extends FastSyncChainDownloader { @@ -37,7 +38,8 @@ public static ChainDownloader create( final EthContext ethContext, final SyncState syncState, final MetricsSystem metricsSystem, - final FastSyncState fastSyncState) { + final FastSyncState fastSyncState, + final SyncDurationMetrics syncDurationMetrics) { final SyncTargetManager syncTargetManager = new SyncTargetManager( @@ -55,6 +57,7 @@ public static ChainDownloader create( new CheckpointSyncDownloadPipelineFactory( config, protocolSchedule, protocolContext, ethContext, fastSyncState, metricsSystem), ethContext.getScheduler(), - metricsSystem); + metricsSystem, + syncDurationMetrics); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java index 06bf8aace6a..7f6bbae3f31 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java @@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; @@ -155,7 +156,8 @@ private FastSyncState updateStats(final FastSyncState fastSyncState) { return fastSyncState; } - public ChainDownloader createChainDownloader(final FastSyncState currentState) { + public ChainDownloader createChainDownloader( + final FastSyncState currentState, final SyncDurationMetrics syncDurationMetrics) { return FastSyncChainDownloader.create( syncConfig, worldStateStorageCoordinator, @@ -164,7 +166,8 @@ public ChainDownloader createChainDownloader(final FastSyncState currentState) { ethContext, syncState, metricsSystem, - currentState); + currentState, + syncDurationMetrics); } private CompletableFuture downloadPivotBlockHeader(final Hash hash) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloader.java index 36f56ccfd8b..c36ff7cb482 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloader.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; public class FastSyncChainDownloader { @@ -36,7 +37,8 @@ public static ChainDownloader create( final EthContext ethContext, final SyncState syncState, final MetricsSystem metricsSystem, - final FastSyncState fastSyncState) { + final FastSyncState fastSyncState, + final SyncDurationMetrics syncDurationMetrics) { final SyncTargetManager syncTargetManager = new SyncTargetManager( @@ -53,6 +55,7 @@ public static ChainDownloader create( new FastSyncDownloadPipelineFactory( config, protocolSchedule, protocolContext, ethContext, fastSyncState, metricsSystem), ethContext.getScheduler(), - metricsSystem); + metricsSystem, + syncDurationMetrics); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java index 565824a7808..0aaeefc6d6e 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.tasks.TaskCollection; import org.hyperledger.besu.util.ExceptionUtils; @@ -52,6 +53,7 @@ public class FastSyncDownloader { private final WorldStateDownloader worldStateDownloader; private final TaskCollection taskCollection; private final Path fastSyncDataDirectory; + private final SyncDurationMetrics syncDurationMetrics; private volatile Optional trailingPeerRequirements = Optional.empty(); private final AtomicBoolean running = new AtomicBoolean(false); @@ -66,7 +68,8 @@ public FastSyncDownloader( final FastSyncStateStorage fastSyncStateStorage, final TaskCollection taskCollection, final Path fastSyncDataDirectory, - final FastSyncState initialFastSyncState) { + final FastSyncState initialFastSyncState, + final SyncDurationMetrics syncDurationMetrics) { this.fastSyncActions = fastSyncActions; this.worldStateStorageCoordinator = worldStateStorageCoordinator; this.worldStateDownloader = worldStateDownloader; @@ -74,6 +77,7 @@ public FastSyncDownloader( this.taskCollection = taskCollection; this.fastSyncDataDirectory = fastSyncDataDirectory; this.initialFastSyncState = initialFastSyncState; + this.syncDurationMetrics = syncDurationMetrics; } public CompletableFuture start() { @@ -81,6 +85,7 @@ public CompletableFuture start() { throw new IllegalStateException("SyncDownloader already running"); } LOG.info("Starting pivot-based sync"); + return start(initialFastSyncState); } @@ -189,7 +194,8 @@ protected CompletableFuture downloadChainAndWorldState( } final CompletableFuture worldStateFuture = worldStateDownloader.run(fastSyncActions, currentState); - final ChainDownloader chainDownloader = fastSyncActions.createChainDownloader(currentState); + final ChainDownloader chainDownloader = + fastSyncActions.createChainDownloader(currentState, syncDurationMetrics); final CompletableFuture chainFuture = chainDownloader.start(); // If either download fails, cancel the other one. diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastDownloaderFactory.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastDownloaderFactory.java index bf9f28db6ce..8b71a57885d 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastDownloaderFactory.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastDownloaderFactory.java @@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -60,7 +61,8 @@ public static Optional> create( final EthContext ethContext, final WorldStateStorageCoordinator worldStateStorageCoordinator, final SyncState syncState, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { final Path fastSyncDataDirectory = dataDirectory.resolve(FAST_SYNC_FOLDER); final FastSyncStateStorage fastSyncStateStorage = @@ -114,7 +116,8 @@ public static Optional> create( syncConfig.getWorldStateMaxRequestsWithoutProgress(), syncConfig.getWorldStateMinMillisBeforeStalling(), clock, - metricsSystem); + metricsSystem, + syncDurationMetrics); final FastSyncDownloader fastSyncDownloader = new FastSyncDownloader<>( new FastSyncActions( @@ -131,7 +134,8 @@ public static Optional> create( fastSyncStateStorage, taskCollection, fastSyncDataDirectory, - fastSyncState); + fastSyncState, + syncDurationMetrics); syncState.setWorldStateDownloadStatus(worldStateDownloader); return Optional.of(fastSyncDownloader); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadState.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadState.java index 3bd6a76c79e..307f98e7f5c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadState.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadState.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldDownloadState; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; import java.time.Clock; @@ -37,13 +38,15 @@ public FastWorldDownloadState( final InMemoryTasksPriorityQueues pendingRequests, final int maxRequestsWithoutProgress, final long minMillisBeforeStalling, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { super( worldStateStorageCoordinator, pendingRequests, maxRequestsWithoutProgress, minMillisBeforeStalling, - clock); + clock, + syncDurationMetrics); } @Override @@ -70,7 +73,9 @@ public synchronized boolean checkCompletion(final BlockHeader header) { // THere are no more inputs to process so make sure we wake up any threads waiting to dequeue // so they can give up waiting. notifyAll(); + LOG.info("Finished downloading world state from peers"); + return true; } else { return false; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloader.java index 559ade5900c..341f1f66acf 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloader.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -51,6 +52,7 @@ public class FastWorldStateDownloader implements WorldStateDownloader { private final WorldStateStorageCoordinator worldStateStorageCoordinator; private final AtomicReference downloadState = new AtomicReference<>(); + private final SyncDurationMetrics syncDurationMetrics; private Optional maybeCompleteTask = Optional.empty(); @@ -63,7 +65,8 @@ public FastWorldStateDownloader( final int maxNodeRequestsWithoutProgress, final long minMillisBeforeStalling, final Clock clock, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final SyncDurationMetrics syncDurationMetrics) { this.ethContext = ethContext; this.worldStateStorageCoordinator = worldStateStorageCoordinator; this.taskCollection = taskCollection; @@ -73,6 +76,7 @@ public FastWorldStateDownloader( this.minMillisBeforeStalling = minMillisBeforeStalling; this.clock = clock; this.metricsSystem = metricsSystem; + this.syncDurationMetrics = syncDurationMetrics; metricsSystem.createIntegerGauge( BesuMetricCategory.SYNCHRONIZER, @@ -137,7 +141,8 @@ public CompletableFuture run( taskCollection, maxNodeRequestsWithoutProgress, minMillisBeforeStalling, - clock); + clock, + syncDurationMetrics); this.downloadState.set(newDownloadState); if (!newDownloadState.downloadWasResumed()) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloader.java index f4a70116269..3a0f6edb086 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloader.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; public class FullSyncChainDownloader { @@ -33,7 +34,8 @@ public static ChainDownloader create( final EthContext ethContext, final SyncState syncState, final MetricsSystem metricsSystem, - final SyncTerminationCondition terminationCondition) { + final SyncTerminationCondition terminationCondition, + final SyncDurationMetrics syncDurationMetrics) { final FullSyncTargetManager syncTargetManager = new FullSyncTargetManager( @@ -55,6 +57,7 @@ public static ChainDownloader create( metricsSystem, terminationCondition), ethContext.getScheduler(), - metricsSystem); + metricsSystem, + syncDurationMetrics); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloader.java index 4484c194460..8f1aca792c3 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloader.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.concurrent.CompletableFuture; @@ -43,7 +44,8 @@ public FullSyncDownloader( final EthContext ethContext, final SyncState syncState, final MetricsSystem metricsSystem, - final SyncTerminationCondition terminationCondition) { + final SyncTerminationCondition terminationCondition, + final SyncDurationMetrics syncDurationMetrics) { this.syncConfig = syncConfig; this.protocolContext = protocolContext; this.syncState = syncState; @@ -56,7 +58,8 @@ public FullSyncDownloader( ethContext, syncState, metricsSystem, - terminationCondition); + terminationCondition, + syncDurationMetrics); } public CompletableFuture start() { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapDownloaderFactory.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapDownloaderFactory.java index 5b40fceb083..5de8ceb9843 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapDownloaderFactory.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapDownloaderFactory.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.trie.CompactEncoding; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -58,7 +59,8 @@ public static Optional> createSnapDownloader( final EthContext ethContext, final WorldStateStorageCoordinator worldStateStorageCoordinator, final SyncState syncState, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { final Path fastSyncDataDirectory = dataDirectory.resolve(FAST_SYNC_FOLDER); final FastSyncStateStorage fastSyncStateStorage = @@ -93,10 +95,7 @@ public static Optional> createSnapDownloader( return Optional.empty(); } - final SnapSyncProcessState snapSyncState = - new SnapSyncProcessState( - fastSyncStateStorage.loadState( - ScheduleBasedBlockHeaderFunctions.create(protocolSchedule))); + final SnapSyncProcessState snapSyncState = new SnapSyncProcessState(fastSyncState); final InMemoryTasksPriorityQueues snapTaskCollection = createSnapWorldStateDownloaderTaskCollection(); @@ -112,7 +111,8 @@ public static Optional> createSnapDownloader( syncConfig.getWorldStateMaxRequestsWithoutProgress(), syncConfig.getWorldStateMinMillisBeforeStalling(), clock, - metricsSystem); + metricsSystem, + syncDurationMetrics); final FastSyncDownloader fastSyncDownloader = new SnapSyncDownloader( new FastSyncActions( @@ -129,7 +129,8 @@ public static Optional> createSnapDownloader( fastSyncStateStorage, snapTaskCollection, fastSyncDataDirectory, - snapSyncState); + snapSyncState, + syncDurationMetrics); syncState.setWorldStateDownloadStatus(snapWorldStateDownloader); return Optional.of(fastSyncDownloader); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncDownloader.java index 00c571f9840..34fd4de5bea 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncDownloader.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.eth.sync.snapsync.request.SnapDataRequest; import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.services.tasks.TaskCollection; import java.nio.file.Path; @@ -35,7 +36,8 @@ public SnapSyncDownloader( final FastSyncStateStorage fastSyncStateStorage, final TaskCollection taskCollection, final Path fastSyncDataDirectory, - final FastSyncState initialFastSyncState) { + final FastSyncState initialFastSyncState, + final SyncDurationMetrics syncDurationMetrics) { super( fastSyncActions, worldStateStorageCoordinator, @@ -43,7 +45,8 @@ public SnapSyncDownloader( fastSyncStateStorage, taskCollection, fastSyncDataDirectory, - initialFastSyncState); + initialFastSyncState, + syncDurationMetrics); } @Override diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadState.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadState.java index b8c8a784ab6..41beaafa6a4 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadState.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadState.java @@ -36,6 +36,8 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; +import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.tasks.InMemoryTaskQueue; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -92,6 +94,8 @@ public class SnapWorldDownloadState extends WorldDownloadState // metrics around the snapsync private final SnapSyncMetricsManager metricsManager; + private final AtomicBoolean trieHealStartedBefore = new AtomicBoolean(false); + public SnapWorldDownloadState( final WorldStateStorageCoordinator worldStateStorageCoordinator, final SnapSyncStatePersistenceManager snapContext, @@ -102,13 +106,15 @@ public SnapWorldDownloadState( final long minMillisBeforeStalling, final SnapSyncMetricsManager metricsManager, final Clock clock, - final EthContext ethContext) { + final EthContext ethContext, + final SyncDurationMetrics syncDurationMetrics) { super( worldStateStorageCoordinator, pendingRequests, maxRequestsWithoutProgress, minMillisBeforeStalling, - clock); + clock, + syncDurationMetrics); this.snapContext = snapContext; this.blockchain = blockchain; this.snapSyncState = snapSyncState; @@ -116,46 +122,34 @@ public SnapWorldDownloadState( this.blockObserverId = blockchain.observeBlockAdded(createBlockchainObserver()); this.ethContext = ethContext; - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_account_requests_current", - "Number of account pending requests for snap sync world state download", - pendingAccountRequests::size); - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_storage_requests_current", - "Number of storage pending requests for snap sync world state download", - pendingStorageRequests::size); - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_big_storage_requests_current", - "Number of storage pending requests for snap sync world state download", - pendingLargeStorageRequests::size); - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_code_requests_current", - "Number of code pending requests for snap sync world state download", - pendingCodeRequests::size); - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_trie_node_requests_current", - "Number of trie node pending requests for snap sync world state download", - pendingTrieNodeRequests::size); - } - - @Override - public synchronized void notifyTaskAvailable() { - notifyAll(); + final MetricsSystem metricsSystem = metricsManager.getMetricsSystem(); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_account_requests_current", + "Number of account pending requests for snap sync world state download", + pendingAccountRequests::size); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_storage_requests_current", + "Number of storage pending requests for snap sync world state download", + pendingStorageRequests::size); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_big_storage_requests_current", + "Number of storage pending requests for snap sync world state download", + pendingLargeStorageRequests::size); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_code_requests_current", + "Number of code pending requests for snap sync world state download", + pendingCodeRequests::size); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_trie_node_requests_current", + "Number of trie node pending requests for snap sync world state download", + pendingTrieNodeRequests::size); + syncDurationMetrics.startTimer( + SyncDurationMetrics.Labels.SNAP_INITIAL_WORLD_STATE_DOWNLOAD_DURATION); } @Override @@ -191,6 +185,9 @@ else if (pivotBlockSelector.isBlockchainBehind()) { // if all snapsync tasks are completed and the healing was running and the blockchain is not // behind the pivot block else { + syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.SNAP_WORLD_STATE_HEALING_DURATION); + syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.CHAIN_DOWNLOAD_DURATION); + // If the flat database healing process is not in progress and the flat database mode is // FULL if (!snapSyncState.isHealFlatDatabaseInProgress() @@ -217,6 +214,7 @@ else if (pivotBlockSelector.isBlockchainBehind()) { // Clear the snap context snapContext.clear(); internalFuture.complete(null); + return true; } } @@ -236,6 +234,12 @@ protected synchronized void cleanupQueues() { /** Method to start the healing process of the trie */ public synchronized void startTrieHeal() { + if (trieHealStartedBefore.compareAndSet(false, true)) { + syncDurationMetrics.stopTimer( + SyncDurationMetrics.Labels.SNAP_INITIAL_WORLD_STATE_DOWNLOAD_DURATION); + + syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.SNAP_WORLD_STATE_HEALING_DURATION); + } snapContext.clearAccountRangeTasks(); snapSyncState.setHealTrieStatus(true); // Try to find a new pivot block before starting the healing process @@ -272,6 +276,7 @@ public synchronized void reloadTrieHeal() { public synchronized void startFlatDatabaseHeal(final BlockHeader header) { LOG.info("Initiating the healing process for the flat database"); + syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.FLAT_DB_HEAL); snapSyncState.setHealFlatDatabaseInProgress(true); final Map ranges = RangeManager.generateAllRanges(16); ranges.forEach( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldStateDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldStateDownloader.java index 9ae49b93c77..fc9d0d8ef10 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldStateDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldStateDownloader.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -67,6 +68,7 @@ public class SnapWorldStateDownloader implements WorldStateDownloader { private final WorldStateStorageCoordinator worldStateStorageCoordinator; private final AtomicReference downloadState = new AtomicReference<>(); + private final SyncDurationMetrics syncDurationMetrics; public SnapWorldStateDownloader( final EthContext ethContext, @@ -79,7 +81,8 @@ public SnapWorldStateDownloader( final int maxNodeRequestsWithoutProgress, final long minMillisBeforeStalling, final Clock clock, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final SyncDurationMetrics syncDurationMetrics) { this.ethContext = ethContext; this.protocolContext = protocolContext; this.worldStateStorageCoordinator = worldStateStorageCoordinator; @@ -91,6 +94,7 @@ public SnapWorldStateDownloader( this.minMillisBeforeStalling = minMillisBeforeStalling; this.clock = clock; this.metricsSystem = metricsSystem; + this.syncDurationMetrics = syncDurationMetrics; metricsSystem.createIntegerGauge( BesuMetricCategory.SYNCHRONIZER, @@ -148,7 +152,8 @@ public CompletableFuture run( minMillisBeforeStalling, snapsyncMetricsManager, clock, - ethContext); + ethContext, + syncDurationMetrics); final Map ranges = RangeManager.generateAllRanges(16); snapsyncMetricsManager.initRange(ranges); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldDownloadState.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldDownloadState.java index fd3ae682da9..4945713ae3c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldDownloadState.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldDownloadState.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.manager.task.EthTask; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; import org.hyperledger.besu.services.tasks.Task; import org.hyperledger.besu.services.tasks.TasksPriorityProvider; @@ -37,6 +38,7 @@ public abstract class WorldDownloadState { private static final Logger LOG = LoggerFactory.getLogger(WorldDownloadState.class); + protected final SyncDurationMetrics syncDurationMetrics; private boolean downloadWasResumed; protected final InMemoryTasksPriorityQueues pendingRequests; @@ -61,7 +63,8 @@ public WorldDownloadState( final InMemoryTasksPriorityQueues pendingRequests, final int maxRequestsWithoutProgress, final long minMillisBeforeStalling, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { this.worldStateStorageCoordinator = worldStateStorageCoordinator; this.minMillisBeforeStalling = minMillisBeforeStalling; this.timestampOfLastProgress = clock.millis(); @@ -69,6 +72,7 @@ public WorldDownloadState( this.pendingRequests = pendingRequests; this.maxRequestsWithoutProgress = maxRequestsWithoutProgress; this.clock = clock; + this.syncDurationMetrics = syncDurationMetrics; this.internalFuture = new CompletableFuture<>(); this.downloadFuture = new CompletableFuture<>(); this.internalFuture.whenComplete(this::cleanup); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloaderTest.java index c8304f5b8d7..f4402349058 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloaderTest.java @@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncTarget; import org.hyperledger.besu.ethereum.eth.sync.tasks.exceptions.InvalidBlockException; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.services.pipeline.Pipeline; @@ -69,13 +70,15 @@ public class PipelineChainDownloaderTest { public void setUp() { syncTarget = new SyncTarget(peer1, commonAncestor); syncTarget2 = new SyncTarget(peer2, commonAncestor); + final NoOpMetricsSystem noOpMetricsSystem = new NoOpMetricsSystem(); chainDownloader = new PipelineChainDownloader( syncState, syncTargetManager, downloadPipelineFactory, scheduler, - new NoOpMetricsSystem()); + noOpMetricsSystem, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @Test diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java index c623b553f19..43f03100a75 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java @@ -40,6 +40,7 @@ import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -141,7 +142,8 @@ private ChainDownloader downloader( ethContext, syncState, new NoOpMetricsSystem(), - new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get())); + new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get()), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @ParameterizedTest diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java index b5be361bf4b..37ca5be2e99 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java @@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -115,7 +116,8 @@ public void shouldThrowIfSyncModeChangedWhileFastSyncIncomplete( ethContext, worldStateStorageCoordinator, syncState, - clock)) + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .isInstanceOf(IllegalStateException.class); } @@ -139,7 +141,8 @@ public void shouldNotThrowIfSyncModeChangedWhileFastSyncComplete( ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); assertThat(result).isEmpty(); } @@ -166,7 +169,8 @@ public void shouldNotThrowWhenFastSyncModeRequested(final DataStorageFormat data ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(mutableBlockchain).getChainHeadBlockNumber(); } @@ -200,7 +204,8 @@ public void shouldClearWorldStateDuringFastSyncWhenStateQueDirectoryExists( ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateKeyValueStorage).clear(); assertThat(Files.exists(stateQueueDir)).isFalse(); @@ -236,7 +241,8 @@ public void shouldCrashWhenStateQueueIsNotDirectory(final DataStorageFormat data ethContext, worldStateStorageCoordinator, syncState, - clock)) + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .isInstanceOf(IllegalStateException.class); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java index f7a8a9ee545..34014246d28 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -111,7 +112,8 @@ private ChainDownloader downloader( ethContext, syncState, new NoOpMetricsSystem(), - new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get())); + new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get()), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @ParameterizedTest diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java index e929b72ff99..13444a91278 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java @@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.tasks.TaskCollection; @@ -105,7 +106,8 @@ public void setup(final DataStorageFormat dataStorageFormat) { storage, taskCollection, fastSyncDataDirectory, - FastSyncState.EMPTY_SYNC_STATE); + FastSyncState.EMPTY_SYNC_STATE, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @ParameterizedTest @@ -119,7 +121,8 @@ public void shouldCompleteFastSyncSuccessfully(final DataStorageFormat dataStora .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( @@ -131,7 +134,9 @@ public void shouldCompleteFastSyncSuccessfully(final DataStorageFormat dataStora verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); verify(storage).storeState(downloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(chainDownloader).start(); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); @@ -148,7 +153,9 @@ public void shouldResumeFastSync(final DataStorageFormat dataStorageFormat) { final CompletableFuture complete = completedFuture(fastSyncState); when(fastSyncActions.selectPivotBlock(fastSyncState)).thenReturn(complete); when(fastSyncActions.downloadPivotBlockHeader(fastSyncState)).thenReturn(complete); - when(fastSyncActions.createChainDownloader(fastSyncState)).thenReturn(chainDownloader); + when(fastSyncActions.createChainDownloader( + fastSyncState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) + .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)))) @@ -162,14 +169,16 @@ public void shouldResumeFastSync(final DataStorageFormat dataStorageFormat) { storage, taskCollection, fastSyncDataDirectory, - fastSyncState); + fastSyncState, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); final CompletableFuture result = resumedDownloader.start(); verify(fastSyncActions).selectPivotBlock(fastSyncState); verify(fastSyncActions).downloadPivotBlockHeader(fastSyncState); verify(storage).storeState(fastSyncState); - verify(fastSyncActions).createChainDownloader(fastSyncState); + verify(fastSyncActions) + .createChainDownloader(fastSyncState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(chainDownloader).start(); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); @@ -206,7 +215,8 @@ public void shouldAbortIfWorldStateDownloadFails(final DataStorageFormat dataSto .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -218,7 +228,9 @@ public void shouldAbortIfWorldStateDownloadFails(final DataStorageFormat dataSto verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); verify(storage).storeState(downloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -246,7 +258,8 @@ public void shouldAbortIfChainDownloadFails(final DataStorageFormat dataStorageF .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -257,7 +270,9 @@ public void shouldAbortIfChainDownloadFails(final DataStorageFormat dataStorageF verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions); @@ -321,7 +336,8 @@ public void shouldNotConsiderFastSyncCompleteIfOnlyWorldStateDownloadIsComplete( .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -332,7 +348,9 @@ public void shouldNotConsiderFastSyncCompleteIfOnlyWorldStateDownloadIsComplete( verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions); @@ -359,7 +377,8 @@ public void shouldNotConsiderFastSyncCompleteIfOnlyChainDownloadIsComplete( .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -370,7 +389,9 @@ public void shouldNotConsiderFastSyncCompleteIfOnlyChainDownloadIsComplete( verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions); @@ -407,7 +428,8 @@ public void shouldResetFastSyncStateAndRestartProcessIfWorldStateIsUnavailable( completedFuture(selectPivotBlockState), completedFuture(secondSelectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -418,7 +440,8 @@ public void shouldResetFastSyncStateAndRestartProcessIfWorldStateIsUnavailable( when(fastSyncActions.downloadPivotBlockHeader(secondSelectPivotBlockState)) .thenReturn(completedFuture(secondDownloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(secondDownloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(secondChainDownloader); when(secondChainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( @@ -430,7 +453,9 @@ public void shouldResetFastSyncStateAndRestartProcessIfWorldStateIsUnavailable( verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); verify(storage).storeState(downloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -446,7 +471,9 @@ public void shouldResetFastSyncStateAndRestartProcessIfWorldStateIsUnavailable( verify(fastSyncActions, times(2)).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(secondSelectPivotBlockState); verify(storage).storeState(secondDownloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(secondDownloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(secondPivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -481,7 +508,8 @@ public void shouldResetFastSyncStateAndRestartProcessIfANonFastSyncExceptionOccu completedFuture(selectPivotBlockState), completedFuture(secondSelectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -494,7 +522,8 @@ public void shouldResetFastSyncStateAndRestartProcessIfANonFastSyncExceptionOccu when(fastSyncActions.downloadPivotBlockHeader(secondSelectPivotBlockState)) .thenReturn(completedFuture(secondDownloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(secondDownloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(secondChainDownloader); when(secondChainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( @@ -506,7 +535,9 @@ public void shouldResetFastSyncStateAndRestartProcessIfANonFastSyncExceptionOccu verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); verify(storage).storeState(downloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -524,7 +555,9 @@ public void shouldResetFastSyncStateAndRestartProcessIfANonFastSyncExceptionOccu verify(fastSyncActions, times(2)).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(secondSelectPivotBlockState); verify(storage).storeState(secondDownloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(secondDownloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(secondPivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -556,7 +589,8 @@ public void shouldNotAllowPeersBeforePivotBlockOnceSelected( .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(new CompletableFuture<>()); when(worldStateDownloader.run( @@ -581,7 +615,8 @@ public void shouldNotHaveTrailingPeerRequirementsAfterDownloadCompletes( .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java index a808ac7078a..e3d2a37cd0c 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; @@ -100,7 +101,8 @@ public void setUp(final DataStorageFormat storageFormat) { pendingRequests, MAX_REQUESTS_WITHOUT_PROGRESS, MIN_MILLIS_BEFORE_STALLING, - clock); + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); assertThat(downloadState.isDownloading()).isTrue(); downloadState.setRootNodeData(ROOT_NODE_DATA); future = downloadState.getDownloadFuture(); 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 3a29a444a45..75fe892aebd 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 @@ -64,6 +64,7 @@ import org.hyperledger.besu.evm.account.AccountStorageEntry; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.worldstate.WorldState; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -1051,7 +1052,8 @@ private WorldStateDownloader createDownloader( config.getWorldStateMaxRequestsWithoutProgress(), config.getWorldStateMinMillisBeforeStalling(), TestClock.fixed(), - new NoOpMetricsSystem()); + new NoOpMetricsSystem(), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private WorldStatePreimageStorage createPreimageStorage() { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderForkTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderForkTest.java index a46aff56700..d7b5970098e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderForkTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderForkTest.java @@ -32,6 +32,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -89,7 +90,8 @@ private ChainDownloader downloader(final SynchronizerConfiguration syncConfig) { ethContext, syncState, metricsSystem, - SyncTerminationCondition.never()); + SyncTerminationCondition.never(), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private ChainDownloader downloader() { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java index ded65f6a122..ac7f0fb8257 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java @@ -42,6 +42,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -121,7 +122,8 @@ private ChainDownloader downloader(final SynchronizerConfiguration syncConfig) { ethContext, syncState, metricsSystem, - SyncTerminationCondition.never()); + SyncTerminationCondition.never(), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private ChainDownloader downloader() { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java index 4eeb3bbc635..311ccf5de30 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -107,7 +108,8 @@ private ChainDownloader downloader( ethContext, syncState, metricsSystem, - terminalCondition); + terminalCondition, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private SynchronizerConfiguration.Builder syncConfigBuilder() { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java index a44ddc07bb0..63e41f6d25c 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -96,7 +97,8 @@ private FullSyncDownloader downloader(final SynchronizerConfiguration syncConfig ethContext, syncState, metricsSystem, - SyncTerminationCondition.never()); + SyncTerminationCondition.never(), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @ParameterizedTest diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java index d1e90b5eb6e..24e4869960e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java @@ -46,6 +46,7 @@ import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; @@ -137,7 +138,8 @@ public void setUp(final DataStorageFormat storageFormat) { MIN_MILLIS_BEFORE_STALLING, metricsManager, clock, - ethContext); + ethContext, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); final DynamicPivotBlockSelector dynamicPivotBlockManager = mock(DynamicPivotBlockSelector.class); doAnswer( diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/SyncDurationMetrics.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/SyncDurationMetrics.java new file mode 100644 index 00000000000..d6fc9370097 --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/SyncDurationMetrics.java @@ -0,0 +1,91 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics; + +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.MetricsSystem; +import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; +import org.hyperledger.besu.plugin.services.metrics.OperationTimer; + +import java.util.HashMap; + +/** + * This class manages the synchronization duration metrics for the Hyperledger Besu project. It + * provides methods to start and stop timers for various synchronization phases. + */ +public class SyncDurationMetrics { + + /** A {@link SyncDurationMetrics} instance that does not record any metrics. */ + public static final SyncDurationMetrics NO_OP_SYNC_DURATION_METRICS = + new SyncDurationMetrics(new NoOpMetricsSystem()); + + private final LabelledMetric timer; + + private final HashMap timers = new HashMap<>(); + + /** + * Creates a new {@link SyncDurationMetrics} instance. + * + * @param metricsSystem The {@link MetricsSystem} to use to record metrics. + */ + public SyncDurationMetrics(final MetricsSystem metricsSystem) { + timer = + metricsSystem.createSimpleLabelledTimer( + BesuMetricCategory.SYNCHRONIZER, "sync_duration", "Time taken to sync", "name"); + } + + /** + * Starts a timer for the given synchronization phase. + * + * @param label The synchronization phase to start the timer for. + */ + public void startTimer(final Labels label) { + timers.computeIfAbsent(label.name(), k -> timer.labels(label.name()).startTimer()); + } + + /** + * Stops the timer for the given synchronization phase. + * + * @param label The synchronization phase to stop the timer for. + */ + public void stopTimer(final Labels label) { + OperationTimer.TimingContext context = timers.remove(label.name()); + if (context != null) { + context.stopTimer(); + } + } + + /** Enum representing the different synchronization phases. */ + public enum Labels { + /** + * Total time taken to get into sync. It is useful for SNAP and CHECKPOINT sync-modes only. + * + *

Total sync duration includes the separate stages mentioned below, some of which occur in + * parallel. + * + *

Total sync duration excludes the backwards sync stage due to implementation challenges. + * The backwards sync should be a very short duration following the other sync stages. + */ + TOTAL_SYNC_DURATION, + /** Time taken to download the chain data (headers, blocks, receipts). */ + CHAIN_DOWNLOAD_DURATION, + /** Time taken to download the initial world state, before the healing step. */ + SNAP_INITIAL_WORLD_STATE_DOWNLOAD_DURATION, + /** Time taken to heal the world state, after the initial download. */ + SNAP_WORLD_STATE_HEALING_DURATION, + /** Time taken to do the flat database heal. */ + FLAT_DB_HEAL; + } +} 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 2b3db497b35..2d1ee26cfd1 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 @@ -104,6 +104,15 @@ public static LabelledMetric getCounterLabelledMetric(final int labelCo } } + @Override + public LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + return getOperationTimerLabelledMetric(labelNames.length); + } + @Override public LabelledMetric createLabelledTimer( final MetricCategory category, 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 c52dd037f76..ca1dc5dd3a3 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 @@ -231,6 +231,15 @@ public LabelledMetric createLabelledCounter( }); } + @Override + public LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + return createLabelledTimer(category, name, help, labelNames); + } + @Override public LabelledMetric createLabelledTimer( final MetricCategory category, 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 218f5755101..653f448311f 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 @@ -40,6 +40,7 @@ import io.prometheus.client.Collector.MetricFamilySamples.Sample; import io.prometheus.client.CollectorRegistry; import io.prometheus.client.Counter; +import io.prometheus.client.Histogram; import io.prometheus.client.Summary; import io.prometheus.client.hotspot.BufferPoolsExports; import io.prometheus.client.hotspot.ClassLoadingExports; @@ -139,6 +140,27 @@ public LabelledMetric createLabelledTimer( }); } + @Override + public LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + final String metricName = convertToPrometheusName(category, name); + return cachedTimers.computeIfAbsent( + metricName, + (k) -> { + if (timersEnabled && isCategoryEnabled(category)) { + final Histogram histogram = + Histogram.build(metricName, help).labelNames(labelNames).buckets(1D).create(); + addCollectorUnchecked(category, histogram); + return new PrometheusSimpleTimer(histogram); + } else { + return NoOpMetricsSystem.getOperationTimerLabelledMetric(labelNames.length); + } + }); + } + @Override public void createGauge( final MetricCategory category, 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 new file mode 100644 index 00000000000..24799cb33d2 --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java @@ -0,0 +1,35 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.metrics.prometheus; + +import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; +import org.hyperledger.besu.plugin.services.metrics.OperationTimer; + +import io.prometheus.client.Histogram; + +class PrometheusSimpleTimer implements LabelledMetric { + + private final Histogram histogram; + + public PrometheusSimpleTimer(final Histogram histogram) { + this.histogram = histogram; + } + + @Override + public OperationTimer labels(final String... labels) { + final Histogram.Child metric = histogram.labels(labels); + return () -> metric.startTimer()::observeDuration; + } +} 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 9e4b9d1ef96..2e0ea006db0 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 @@ -75,6 +75,15 @@ public LabelledMetric createLabelledTimer( return labelValues -> NoOpMetricsSystem.NO_OP_OPERATION_TIMER; } + @Override + public LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + return labelValues -> NoOpMetricsSystem.NO_OP_OPERATION_TIMER; + } + @Override public void createGauge( final MetricCategory category, diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index af8da71a7f1..66c8e34837b 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,7 @@ Calculated : ${currentHash} tasks.register('checkAPIChanges', FileStateChecker) { description = "Checks that the API for the Plugin-API project does not change without deliberate thought" files = sourceSets.main.allJava.files - knownHash = '2tFIKwEd8T5I37ywbFnVcMwTR8HiiCC6gO1Chd3hZp8=' + knownHash = 'V/bdVbzJLjdwch266dHHuxIGwiCRhS4w3jDwHt4TWqg=' } check.dependsOn('checkAPIChanges') 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 a72eb182b08..80e02a6dba7 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 @@ -89,6 +89,34 @@ default OperationTimer createTimer( LabelledMetric createLabelledTimer( MetricCategory category, String name, String help, String... labelNames); + /** + * Creates a simple Timer. + * + * @param category The {@link MetricCategory} this timer is assigned to. + * @param name A name for this metric. + * @param help A human readable description of the metric. + * @return The created Timer instance. + */ + default OperationTimer createSimpleTimer( + final MetricCategory category, final String name, final String help) { + return createSimpleLabelledTimer(category, name, help).labels(); + } + + /** + * Creates a simple Timer with assigned labels. + * + * @param category The {@link MetricCategory} this timer is assigned to. + * @param name A name for this metric. + * @param help A human readable description of the metric. + * @param labelNames An array of labels to assign to the Timer. + * @return The created Timer instance. + */ + LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames); + /** * Creates a gauge for displaying double vales. A gauge is a metric to report the current value. * The metric value may go up or down.