Skip to content

Commit 053af58

Browse files
authored
Fix/fastheader stackoverflow (#7908)
1 parent 495b7ed commit 053af58

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,47 @@ public async Task Can_prepare_3_requests_in_a_row()
7272
await feed.PrepareRequest();
7373
}
7474

75+
[Test]
76+
public async Task Can_handle_forks_with_persisted_headers()
77+
{
78+
IBlockTree remoteBlockTree = CachedBlockTreeBuilder.OfLength(1000);
79+
IBlockTree forkedBlockTree = Build.A.BlockTree().WithStateRoot(Keccak.Compute("1245")).OfChainLength(1000).TestObject;
80+
BlockHeader pivotBlock = remoteBlockTree.FindHeader(999)!;
81+
82+
IBlockTree blockTree = Build.A.BlockTree().TestObject;
83+
for (int i = 500; i < 1000; i++)
84+
{
85+
blockTree.Insert(forkedBlockTree.FindHeader(i)!).Should().Be(AddBlockResult.Added);
86+
}
87+
88+
ISyncReport syncReport = Substitute.For<ISyncReport>();
89+
syncReport.FastBlocksHeaders.Returns(new MeasuredProgress());
90+
syncReport.HeadersInQueue.Returns(new MeasuredProgress());
91+
HeadersSyncFeed feed = new(
92+
blockTree: blockTree,
93+
syncPeerPool: Substitute.For<ISyncPeerPool>(),
94+
syncConfig: new TestSyncConfig
95+
{
96+
FastSync = true,
97+
PivotNumber = pivotBlock.Number.ToString(),
98+
PivotHash = pivotBlock.Hash!.ToString(),
99+
PivotTotalDifficulty = pivotBlock.TotalDifficulty.ToString()!,
100+
},
101+
syncReport: syncReport,
102+
logManager: LimboLogs.Instance);
103+
104+
feed.InitializeFeed();
105+
while (true)
106+
{
107+
var batch = await feed.PrepareRequest();
108+
if (batch is null) break;
109+
batch.Response = remoteBlockTree.FindHeaders(
110+
remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash!, batch.RequestSize, 0,
111+
false)!;
112+
feed.HandleResponse(batch);
113+
}
114+
}
115+
75116
[Test]
76117
public async Task When_next_header_hash_update_is_delayed_do_not_drop_peer()
77118
{

src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -476,9 +476,9 @@ private static HeadersSyncBatch BuildDependentBatch(HeadersSyncBatch batch, long
476476
return dependentBatch;
477477
}
478478

479-
private void EnqueueBatch(HeadersSyncBatch batch)
479+
private void EnqueueBatch(HeadersSyncBatch batch, bool skipPersisted = false)
480480
{
481-
HeadersSyncBatch? left = ProcessPersistedPortion(batch);
481+
HeadersSyncBatch? left = skipPersisted ? batch : ProcessPersistedPortion(batch);
482482
if (left is not null)
483483
{
484484
_pending.Enqueue(batch);
@@ -638,7 +638,7 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch)
638638
{
639639
batch.Response?.Dispose();
640640
batch.Response = null;
641-
EnqueueBatch(batch);
641+
EnqueueBatch(batch, true);
642642
}
643643
else
644644
{
@@ -733,7 +733,7 @@ bool ValidateFirstHeader(BlockHeader header)
733733

734734
if (_dependencies.ContainsKey(header.Number))
735735
{
736-
EnqueueBatch(batch);
736+
EnqueueBatch(batch, true);
737737
throw new InvalidOperationException($"Only one header dependency expected ({batch})");
738738
}
739739
long lastNumber = -1;

0 commit comments

Comments
 (0)