From 707a45176654bc09fc0e16ea001d7fc49529246b Mon Sep 17 00:00:00 2001 From: Damian Orzechowski Date: Wed, 11 Dec 2024 10:35:08 +0100 Subject: [PATCH 1/7] Add additional block lag for better sync mode switching --- .../ParallelSync/MultiSyncModeSelector.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs index 39eb81fc72d..dbb98c72d83 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs @@ -38,6 +38,7 @@ public class MultiSyncModeSelector : ISyncModeSelector /// Number of blocks before the best peer's head when we switch from fast sync to full sync /// public const int FastSyncLag = 32; + public const int FastChainLag = 6; /// /// How many blocks can fast sync stay behind while state nodes is still syncing @@ -399,7 +400,7 @@ private bool ShouldBeInFastSyncMode(Snapshot best) // and we need to sync away from it. // Note: its ok if target block height is not accurate as long as long full sync downloader does not stop // earlier than this condition below which would cause a hang. - bool notReachedFullSyncTransition = best.Header < best.TargetBlock - FastSyncLag; + bool notReachedFullSyncTransition = best.Header < best.TargetBlock - FastSyncLag - FastChainLag; bool notInAStickyFullSync = !IsInAStickyFullSyncMode(best); bool notHasJustStartedFullSync = !HasJustStartedFullSync(best); @@ -589,7 +590,7 @@ private bool ShouldBeInStateSyncMode(Snapshot best) bool notInFastSync = !best.IsInFastSync; bool notNeedToWaitForHeaders = NotNeedToWaitForHeaders; bool stickyStateNodes = best.TargetBlock - best.Header < (FastSyncLag + StickyStateNodesDelta); - bool stateNotDownloadedYet = (best.TargetBlock - best.State > FastSyncLag || + bool stateNotDownloadedYet = (best.TargetBlock - best.State > FastSyncLag + FastChainLag || best.Header > best.State && best.Header > best.Block); bool notInAStickyFullSync = !IsInAStickyFullSyncMode(best); bool notHasJustStartedFullSync = !HasJustStartedFullSync(best); @@ -644,7 +645,7 @@ private bool ShouldBeInStateNodesMode(Snapshot best) private bool ShouldBeInSnapRangesPhase(Snapshot best) { bool isInStateSync = best.IsInStateSync; - bool isCloseToHead = best.TargetBlock >= best.Header && (best.TargetBlock - best.Header) <= FastSyncLag; + bool isCloseToHead = best.TargetBlock >= best.Header && (best.TargetBlock - best.Header) <= FastSyncLag + FastChainLag; bool snapNotFinished = !_syncProgressResolver.IsSnapGetRangesFinished(); if (_logger.IsTrace) From 7809cac73aa6f98535d4490fe6d330db07fccc4e Mon Sep 17 00:00:00 2001 From: Damian Orzechowski Date: Wed, 11 Dec 2024 17:44:27 +0100 Subject: [PATCH 2/7] Modified state availability condition --- .../ParallelSync/MultiSyncModeSelector.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs index dbb98c72d83..a9f92bcbaef 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs @@ -590,8 +590,8 @@ private bool ShouldBeInStateSyncMode(Snapshot best) bool notInFastSync = !best.IsInFastSync; bool notNeedToWaitForHeaders = NotNeedToWaitForHeaders; bool stickyStateNodes = best.TargetBlock - best.Header < (FastSyncLag + StickyStateNodesDelta); - bool stateNotDownloadedYet = (best.TargetBlock - best.State > FastSyncLag + FastChainLag || - best.Header > best.State && best.Header > best.Block); + bool stateNotDownloadedYet = (best.TargetBlock - best.State > (FastSyncLag + FastChainLag) || + best.Header > (best.State + FastChainLag) && best.Header > best.Block); bool notInAStickyFullSync = !IsInAStickyFullSyncMode(best); bool notHasJustStartedFullSync = !HasJustStartedFullSync(best); From 6a22ed7763ff3bf41ff1b83e1bc1ca8e555770bd Mon Sep 17 00:00:00 2001 From: Damian Orzechowski Date: Fri, 13 Dec 2024 10:32:34 +0100 Subject: [PATCH 3/7] Additional logging for testing --- .../ParallelSync/MultiSyncModeSelector.cs | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs index a9f92bcbaef..9ab19492cd6 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs @@ -416,6 +416,14 @@ private bool ShouldBeInFastSyncMode(Snapshot best) notHasJustStartedFullSync && notNeedToWaitForHeaders; + if (_logger.IsInfo && _syncProgressResolver.IsSnapGetRangesFinished()) + { + LogDetailedSyncModeChecks("FAST", + (nameof(notReachedFullSyncTransition), notReachedFullSyncTransition), + (nameof(notInAStickyFullSync), notInAStickyFullSync), + (nameof(notHasJustStartedFullSync), notHasJustStartedFullSync)); + } + if (_logger.IsTrace) { LogDetailedSyncModeChecks("FAST", @@ -460,6 +468,17 @@ private bool ShouldBeInFullSyncMode(Snapshot best) stateSyncFinished && notNeedToWaitForHeaders; + if (_logger.IsInfo && _syncProgressResolver.IsSnapGetRangesFinished()) + { + LogDetailedSyncModeChecks("FULL", + (nameof(postPivotPeerAvailable), postPivotPeerAvailable), + (nameof(hasFastSyncBeenActive), hasFastSyncBeenActive), + (nameof(notInFastSync), notInFastSync), + (nameof(notInStateSync), notInStateSync), + (nameof(stateSyncFinished), stateSyncFinished)); + } + + if (_logger.IsTrace) { LogDetailedSyncModeChecks("FULL", @@ -607,6 +626,15 @@ private bool ShouldBeInStateSyncMode(Snapshot best) notInAStickyFullSync && notNeedToWaitForHeaders; + if (_logger.IsInfo && _syncProgressResolver.IsSnapGetRangesFinished()) + { + LogDetailedSyncModeChecks("STATE", + ($"{nameof(notInFastSync)}||{nameof(stickyStateNodes)}", notInFastSync || stickyStateNodes), + (nameof(stateNotDownloadedYet), stateNotDownloadedYet), + (nameof(notInAStickyFullSync), notInAStickyFullSync), + (nameof(notHasJustStartedFullSync), notHasJustStartedFullSync)); + } + if (_logger.IsTrace) { LogDetailedSyncModeChecks("STATE", @@ -632,6 +660,13 @@ private bool ShouldBeInStateNodesMode(Snapshot best) bool result = isInStateSync && (snapSyncDisabled || snapRangesFinished); + if (_logger.IsInfo && _syncProgressResolver.IsSnapGetRangesFinished()) + { + LogDetailedSyncModeChecks("STATE_NODES", + (nameof(isInStateSync), isInStateSync), + ($"{nameof(snapSyncDisabled)}||{nameof(snapRangesFinished)}", snapSyncDisabled || snapRangesFinished)); + } + if (_logger.IsTrace) { LogDetailedSyncModeChecks("STATE_NODES", @@ -780,7 +815,7 @@ private void LogDetailedSyncModeChecks(string syncType, params (string Name, boo bool result = checks.All(c => c.IsSatisfied); string text = $"{(result ? " * " : " ")}{syncType,-20}: yes({string.Join(", ", matched)}), no({string.Join(", ", failed)})"; - _logger.Trace(text); + _logger.Info(text); } private ref struct Snapshot From 5be45a35325df0f21328cfa6ffc9c3bd938d9bd2 Mon Sep 17 00:00:00 2001 From: Damian Orzechowski Date: Fri, 13 Dec 2024 19:33:59 +0100 Subject: [PATCH 4/7] Revert "Additional logging for testing" This reverts commit 6a22ed7763ff3bf41ff1b83e1bc1ca8e555770bd. --- .../ParallelSync/MultiSyncModeSelector.cs | 37 +------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs index 9ab19492cd6..a9f92bcbaef 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs @@ -416,14 +416,6 @@ private bool ShouldBeInFastSyncMode(Snapshot best) notHasJustStartedFullSync && notNeedToWaitForHeaders; - if (_logger.IsInfo && _syncProgressResolver.IsSnapGetRangesFinished()) - { - LogDetailedSyncModeChecks("FAST", - (nameof(notReachedFullSyncTransition), notReachedFullSyncTransition), - (nameof(notInAStickyFullSync), notInAStickyFullSync), - (nameof(notHasJustStartedFullSync), notHasJustStartedFullSync)); - } - if (_logger.IsTrace) { LogDetailedSyncModeChecks("FAST", @@ -468,17 +460,6 @@ private bool ShouldBeInFullSyncMode(Snapshot best) stateSyncFinished && notNeedToWaitForHeaders; - if (_logger.IsInfo && _syncProgressResolver.IsSnapGetRangesFinished()) - { - LogDetailedSyncModeChecks("FULL", - (nameof(postPivotPeerAvailable), postPivotPeerAvailable), - (nameof(hasFastSyncBeenActive), hasFastSyncBeenActive), - (nameof(notInFastSync), notInFastSync), - (nameof(notInStateSync), notInStateSync), - (nameof(stateSyncFinished), stateSyncFinished)); - } - - if (_logger.IsTrace) { LogDetailedSyncModeChecks("FULL", @@ -626,15 +607,6 @@ private bool ShouldBeInStateSyncMode(Snapshot best) notInAStickyFullSync && notNeedToWaitForHeaders; - if (_logger.IsInfo && _syncProgressResolver.IsSnapGetRangesFinished()) - { - LogDetailedSyncModeChecks("STATE", - ($"{nameof(notInFastSync)}||{nameof(stickyStateNodes)}", notInFastSync || stickyStateNodes), - (nameof(stateNotDownloadedYet), stateNotDownloadedYet), - (nameof(notInAStickyFullSync), notInAStickyFullSync), - (nameof(notHasJustStartedFullSync), notHasJustStartedFullSync)); - } - if (_logger.IsTrace) { LogDetailedSyncModeChecks("STATE", @@ -660,13 +632,6 @@ private bool ShouldBeInStateNodesMode(Snapshot best) bool result = isInStateSync && (snapSyncDisabled || snapRangesFinished); - if (_logger.IsInfo && _syncProgressResolver.IsSnapGetRangesFinished()) - { - LogDetailedSyncModeChecks("STATE_NODES", - (nameof(isInStateSync), isInStateSync), - ($"{nameof(snapSyncDisabled)}||{nameof(snapRangesFinished)}", snapSyncDisabled || snapRangesFinished)); - } - if (_logger.IsTrace) { LogDetailedSyncModeChecks("STATE_NODES", @@ -815,7 +780,7 @@ private void LogDetailedSyncModeChecks(string syncType, params (string Name, boo bool result = checks.All(c => c.IsSatisfied); string text = $"{(result ? " * " : " ")}{syncType,-20}: yes({string.Join(", ", matched)}), no({string.Join(", ", failed)})"; - _logger.Info(text); + _logger.Trace(text); } private ref struct Snapshot From c08476c0d85febbcd25b26f1b8f4ca5a2b9bae87 Mon Sep 17 00:00:00 2001 From: Damian Orzechowski Date: Sat, 14 Dec 2024 12:41:56 +0100 Subject: [PATCH 5/7] Placed header state distance in config --- .../Nethermind.Blockchain/Synchronization/ISyncConfig.cs | 3 +++ .../Nethermind.Blockchain/Synchronization/SyncConfig.cs | 5 +++++ .../Nethermind.Runner/configs/linea-mainnet.json | 5 +++-- .../Nethermind.Runner/configs/linea-sepolia.json | 5 +++-- .../ParallelSync/MultiSyncModeSelector.cs | 9 ++++----- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs index 4694d5ead47..bf48359a21c 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs @@ -164,4 +164,7 @@ public interface ISyncConfig : IConfig [ConfigItem(Description = "_Technical._ Run explicit GC after state sync finished.", DefaultValue = "true", HiddenFromDocs = true)] bool GCOnFeedFinished { get; set; } + + [ConfigItem(Description = "_Technical._ Max distance between best suggested header and available state to assume state is synced.", DefaultValue = "0", HiddenFromDocs = true)] + int HeaderStateDistance { get; set; } } diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs index 6ce0c295c5e..06c6785cb76 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs @@ -74,6 +74,11 @@ public string? PivotHash public int StateMinDistanceFromHead { get; set; } = 32; public bool GCOnFeedFinished { get; set; } = true; + /// Additional delay in blocks between best suggested header and synced state to allow faster state switching for PoW chains + /// with higher block processing frequency. Effectively this is the max allowed difference between best header (used as sync + /// pivot) and synced state block, to assume that state is synced and node can start processing blocks + public int HeaderStateDistance { get; set; } = 0; + public override string ToString() { return diff --git a/src/Nethermind/Nethermind.Runner/configs/linea-mainnet.json b/src/Nethermind/Nethermind.Runner/configs/linea-mainnet.json index 1e6ef7ce1f4..d862c5ba1f6 100644 --- a/src/Nethermind/Nethermind.Runner/configs/linea-mainnet.json +++ b/src/Nethermind/Nethermind.Runner/configs/linea-mainnet.json @@ -18,10 +18,11 @@ "SnapSync": true, "PivotNumber": 13020000, "PivotHash": "0x3dbc1fab314e5877280d5d192f0e55ae349500198121b67099c00af378369102", - "PivotTotalDifficulty": "26040001" + "PivotTotalDifficulty": "26040001", + "HeaderStateDistance": 6 }, "JsonRpc": { "Enabled": true, "Port": 8545 } -} \ No newline at end of file +} diff --git a/src/Nethermind/Nethermind.Runner/configs/linea-sepolia.json b/src/Nethermind/Nethermind.Runner/configs/linea-sepolia.json index 37c35b26588..936a574103a 100644 --- a/src/Nethermind/Nethermind.Runner/configs/linea-sepolia.json +++ b/src/Nethermind/Nethermind.Runner/configs/linea-sepolia.json @@ -18,10 +18,11 @@ "SnapSync": true, "PivotNumber": 6830000, "PivotHash": "0x75e380ff226a8b160cdef9c479327c98df28576a4388c90373d2b2931e3e852a", - "PivotTotalDifficulty": "13660001" + "PivotTotalDifficulty": "13660001", + "HeaderStateDistance": 6 }, "JsonRpc": { "Enabled": true, "Port": 8545 } -} \ No newline at end of file +} diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs index a9f92bcbaef..67401e7f18a 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs @@ -38,7 +38,6 @@ public class MultiSyncModeSelector : ISyncModeSelector /// Number of blocks before the best peer's head when we switch from fast sync to full sync /// public const int FastSyncLag = 32; - public const int FastChainLag = 6; /// /// How many blocks can fast sync stay behind while state nodes is still syncing @@ -400,7 +399,7 @@ private bool ShouldBeInFastSyncMode(Snapshot best) // and we need to sync away from it. // Note: its ok if target block height is not accurate as long as long full sync downloader does not stop // earlier than this condition below which would cause a hang. - bool notReachedFullSyncTransition = best.Header < best.TargetBlock - FastSyncLag - FastChainLag; + bool notReachedFullSyncTransition = best.Header < best.TargetBlock - FastSyncLag - _syncConfig.HeaderStateDistance; bool notInAStickyFullSync = !IsInAStickyFullSyncMode(best); bool notHasJustStartedFullSync = !HasJustStartedFullSync(best); @@ -590,8 +589,8 @@ private bool ShouldBeInStateSyncMode(Snapshot best) bool notInFastSync = !best.IsInFastSync; bool notNeedToWaitForHeaders = NotNeedToWaitForHeaders; bool stickyStateNodes = best.TargetBlock - best.Header < (FastSyncLag + StickyStateNodesDelta); - bool stateNotDownloadedYet = (best.TargetBlock - best.State > (FastSyncLag + FastChainLag) || - best.Header > (best.State + FastChainLag) && best.Header > best.Block); + bool stateNotDownloadedYet = (best.TargetBlock - best.State > (FastSyncLag + _syncConfig.HeaderStateDistance) || + best.Header > (best.State + _syncConfig.HeaderStateDistance) && best.Header > best.Block); bool notInAStickyFullSync = !IsInAStickyFullSyncMode(best); bool notHasJustStartedFullSync = !HasJustStartedFullSync(best); @@ -645,7 +644,7 @@ private bool ShouldBeInStateNodesMode(Snapshot best) private bool ShouldBeInSnapRangesPhase(Snapshot best) { bool isInStateSync = best.IsInStateSync; - bool isCloseToHead = best.TargetBlock >= best.Header && (best.TargetBlock - best.Header) <= FastSyncLag + FastChainLag; + bool isCloseToHead = best.TargetBlock >= best.Header && (best.TargetBlock - best.Header) <= FastSyncLag + _syncConfig.HeaderStateDistance; bool snapNotFinished = !_syncProgressResolver.IsSnapGetRangesFinished(); if (_logger.IsTrace) From 177dd67ec786708f0cbf6d183f1f3b362d123f10 Mon Sep 17 00:00:00 2001 From: Damian Orzechowski Date: Tue, 17 Dec 2024 17:20:58 +0100 Subject: [PATCH 6/7] Add test --- .../MultiSyncModeSelectorBeaconTests.cs | 12 +++++++++ .../MultiSyncModeSelectorTests.Scenario.cs | 25 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorBeaconTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorBeaconTests.cs index b47a353f91c..be2dcae22c9 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorBeaconTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorBeaconTests.cs @@ -336,6 +336,18 @@ public void When_just_started_full_sync() .TheSyncModeShouldBe(GetBeaconSyncExpectations(SyncMode.Full)); } + [Test] + public void When_finished_state_sync_and_header_moved_forward() + { + Scenario.GoesLikeThis(_needToWaitForHeaders) + .WhenInBeaconSyncMode(BeaconSync.None) + .IfThisNodeJustFinishedStateSyncButBehindHeader(FastBlocksState.FinishedHeaders) + .AndGoodPeersAreKnown() + .WhenSnapSyncIsConfigured() + .WhenStateAndBestHeaderCanBeBeDifferent(6) //allow best state to be max 6 block apart from best block header + .TheSyncModeShouldBe(SyncMode.Full | SyncMode.FastBodies); + } + [TestCase(FastBlocksState.None)] [TestCase(FastBlocksState.FinishedHeaders)] [TestCase(FastBlocksState.FinishedBodies)] diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTests.Scenario.cs b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTests.Scenario.cs index 8e94ff818b5..e675ab62333 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTests.Scenario.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTests.Scenario.cs @@ -468,6 +468,25 @@ public ScenarioBuilder IfThisNodeJustStartedFullSyncProcessing(FastBlocksState f return this; } + public ScenarioBuilder IfThisNodeJustFinishedStateSyncButBehindHeader(FastBlocksState fastBlocksState = FastBlocksState.FinishedReceipts) + { + long currentBlock = ChainHead.Number - MultiSyncModeSelector.FastSyncLag; + _syncProgressSetups.Add( + () => + { + SyncProgressResolver.FindBestHeader().Returns(currentBlock); + SyncProgressResolver.FindBestFullBlock().Returns(0); //no full blocks available + SyncProgressResolver.FindBestFullState().Returns(currentBlock - 4); //pivot is set to header, but then header follows the head of the chain + SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.IsFastBlocksFinished().Returns(fastBlocksState); + SyncProgressResolver.ChainDifficulty.Returns((UInt256)currentBlock); + SyncProgressResolver.IsSnapGetRangesFinished().Returns(true); + return "just started full sync"; + } + ); + return this; + } + public ScenarioBuilder IfThisNodeRecentlyStartedFullSyncProcessing(FastBlocksState fastBlocksState = FastBlocksState.FinishedReceipts) { long currentBlock = ChainHead.Number - MultiSyncModeSelector.FastSyncLag / 2; @@ -673,6 +692,12 @@ public ScenarioBuilder WhenThisNodeIsLoadingBlocksFromDb() return this; } + public ScenarioBuilder WhenStateAndBestHeaderCanBeBeDifferent(int maxBlockDiff) + { + _overwrites.Add(() => SyncConfig.HeaderStateDistance = maxBlockDiff); + return this; + } + public ScenarioBuilder ThenInAnySyncConfiguration() { WhenFullArchiveSyncIsConfigured(); From 2bf8f3120e0c01bbc8c70fba37b335da6385e3ec Mon Sep 17 00:00:00 2001 From: Damian Orzechowski Date: Wed, 18 Dec 2024 17:21:52 +0100 Subject: [PATCH 7/7] Small refactoring based on review comments --- .../Nethermind.Blockchain/Synchronization/SyncConfig.cs | 3 ++- .../ParallelSync/MultiSyncModeSelector.cs | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs index 06c6785cb76..0207b26417d 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs @@ -73,10 +73,11 @@ public string? PivotHash public int StateMaxDistanceFromHead { get; set; } = 128; public int StateMinDistanceFromHead { get; set; } = 32; public bool GCOnFeedFinished { get; set; } = true; - + /// /// Additional delay in blocks between best suggested header and synced state to allow faster state switching for PoW chains /// with higher block processing frequency. Effectively this is the max allowed difference between best header (used as sync /// pivot) and synced state block, to assume that state is synced and node can start processing blocks + /// public int HeaderStateDistance { get; set; } = 0; public override string ToString() diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs index 67401e7f18a..3459b243bb9 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs @@ -64,6 +64,7 @@ public class MultiSyncModeSelector : ISyncModeSelector private long FastSyncCatchUpHeightDelta => _syncConfig.FastSyncCatchUpHeightDelta ?? FastSyncLag; private bool NotNeedToWaitForHeaders => !_needToWaitForHeaders || FastBlocksHeadersFinished; private long? LastBlockThatEnabledFullSync { get; set; } + private int TotalSyncLag => FastSyncLag + _syncConfig.HeaderStateDistance; private readonly CancellationTokenSource _cancellation = new(); @@ -399,7 +400,7 @@ private bool ShouldBeInFastSyncMode(Snapshot best) // and we need to sync away from it. // Note: its ok if target block height is not accurate as long as long full sync downloader does not stop // earlier than this condition below which would cause a hang. - bool notReachedFullSyncTransition = best.Header < best.TargetBlock - FastSyncLag - _syncConfig.HeaderStateDistance; + bool notReachedFullSyncTransition = best.Header < best.TargetBlock - TotalSyncLag; bool notInAStickyFullSync = !IsInAStickyFullSyncMode(best); bool notHasJustStartedFullSync = !HasJustStartedFullSync(best); @@ -589,7 +590,7 @@ private bool ShouldBeInStateSyncMode(Snapshot best) bool notInFastSync = !best.IsInFastSync; bool notNeedToWaitForHeaders = NotNeedToWaitForHeaders; bool stickyStateNodes = best.TargetBlock - best.Header < (FastSyncLag + StickyStateNodesDelta); - bool stateNotDownloadedYet = (best.TargetBlock - best.State > (FastSyncLag + _syncConfig.HeaderStateDistance) || + bool stateNotDownloadedYet = (best.TargetBlock - best.State > TotalSyncLag || best.Header > (best.State + _syncConfig.HeaderStateDistance) && best.Header > best.Block); bool notInAStickyFullSync = !IsInAStickyFullSyncMode(best); bool notHasJustStartedFullSync = !HasJustStartedFullSync(best); @@ -644,7 +645,7 @@ private bool ShouldBeInStateNodesMode(Snapshot best) private bool ShouldBeInSnapRangesPhase(Snapshot best) { bool isInStateSync = best.IsInStateSync; - bool isCloseToHead = best.TargetBlock >= best.Header && (best.TargetBlock - best.Header) <= FastSyncLag + _syncConfig.HeaderStateDistance; + bool isCloseToHead = best.TargetBlock >= best.Header && (best.TargetBlock - best.Header) <= TotalSyncLag; bool snapNotFinished = !_syncProgressResolver.IsSnapGetRangesFinished(); if (_logger.IsTrace)