Skip to content

Commit baa8f63

Browse files
authored
Fix error on fetching header without total difficulty (#7948)
1 parent 064421b commit baa8f63

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

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

+45-3
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
using Nethermind.Core.Test;
1818
using Nethermind.Core.Test.Builders;
1919
using Nethermind.Logging;
20+
using Nethermind.State.Repositories;
2021
using Nethermind.Stats.Model;
2122
using Nethermind.Synchronization.FastBlocks;
2223
using Nethermind.Synchronization.ParallelSync;
2324
using Nethermind.Synchronization.Peers;
2425
using Nethermind.Synchronization.Reporting;
26+
using Nethermind.Synchronization.SyncLimits;
2527
using NSubstitute;
2628
using NUnit.Framework;
2729
using BlockTree = Nethermind.Blockchain.BlockTree;
@@ -74,6 +76,7 @@ public async Task Can_prepare_3_requests_in_a_row()
7476

7577
[Test]
7678
public async Task Can_handle_forks_with_persisted_headers()
79+
7780
{
7881
IBlockTree remoteBlockTree = CachedBlockTreeBuilder.OfLength(1000);
7982
IBlockTree forkedBlockTree = Build.A.BlockTree().WithStateRoot(Keccak.Compute("1245")).OfChainLength(1000).TestObject;
@@ -461,7 +464,7 @@ public async Task Can_insert_all_good_headers_from_dependent_batch_with_missing_
461464
report.FastBlocksHeaders.Returns(new MeasuredProgress());
462465

463466
ISyncPeerPool syncPeerPool = Substitute.For<ISyncPeerPool>();
464-
using HeadersSyncFeed feed = new(localBlockTree, syncPeerPool, syncConfig, report, new TestLogManager(LogLevel.Trace));
467+
using HeadersSyncFeed feed = new(localBlockTree, syncPeerPool, syncConfig, report, LimboLogs.Instance);
465468
feed.InitializeFeed();
466469
using HeadersSyncBatch? firstBatch = await feed.PrepareRequest();
467470
using HeadersSyncBatch? dependentBatch = await feed.PrepareRequest();
@@ -522,7 +525,7 @@ public async Task Does_not_download_persisted_header()
522525
ISyncReport report = Substitute.For<ISyncReport>();
523526
report.HeadersInQueue.Returns(new MeasuredProgress());
524527
report.FastBlocksHeaders.Returns(new MeasuredProgress());
525-
using HeadersSyncFeed feed = new(localBlockTree, syncPeerPool, syncConfig, report, new TestLogManager(LogLevel.Trace));
528+
using HeadersSyncFeed feed = new(localBlockTree, syncPeerPool, syncConfig, report, LimboLogs.Instance);
526529
feed.InitializeFeed();
527530

528531
void FillBatch(HeadersSyncBatch batch)
@@ -583,13 +586,52 @@ public async Task Limits_persisted_headers_dependency()
583586
ISyncReport report = Substitute.For<ISyncReport>();
584587
report.HeadersInQueue.Returns(new MeasuredProgress());
585588
report.FastBlocksHeaders.Returns(new MeasuredProgress());
586-
using HeadersSyncFeed feed = new(localBlockTree, syncPeerPool, syncConfig, report, new TestLogManager(LogLevel.Trace));
589+
using HeadersSyncFeed feed = new(localBlockTree, syncPeerPool, syncConfig, report, LimboLogs.Instance);
587590
feed.InitializeFeed();
588591

589592
(await feed.PrepareRequest()).Should().NotBe(null);
590593
(await feed.PrepareRequest()).Should().Be(null);
591594
}
592595

596+
[Test]
597+
public async Task Can_use_persisted_header_without_total_difficulty()
598+
{
599+
var peerChain = CachedBlockTreeBuilder.OfLength(1000);
600+
var pivotHeader = peerChain.FindHeader(700)!;
601+
var syncConfig = new TestSyncConfig
602+
{
603+
FastSync = true,
604+
PivotNumber = pivotHeader.Number.ToString(),
605+
PivotHash = pivotHeader.Hash!.ToString(),
606+
PivotTotalDifficulty = pivotHeader.TotalDifficulty.ToString()!
607+
};
608+
609+
IChainLevelInfoRepository levelInfoRepository = new ChainLevelInfoRepository(new TestMemDb());
610+
IBlockTree localBlockTree = Build.A.BlockTree(peerChain.FindBlock(0, BlockTreeLookupOptions.None)!, null)
611+
.WithChainLevelInfoRepository(levelInfoRepository)
612+
.WithSyncConfig(syncConfig).TestObject;
613+
614+
long firstCheckedHeader = pivotHeader.Number - GethSyncLimits.MaxHeaderFetch;
615+
for (long i = firstCheckedHeader - 1; i <= firstCheckedHeader; i++)
616+
{
617+
BlockHeader header = peerChain.FindHeader(i)!;
618+
header.TotalDifficulty = null;
619+
localBlockTree.Insert(header, BlockTreeInsertHeaderOptions.TotalDifficultyNotNeeded).Should().Be(AddBlockResult.Added);
620+
}
621+
levelInfoRepository.Delete(firstCheckedHeader - 1);
622+
623+
ISyncPeerPool syncPeerPool = Substitute.For<ISyncPeerPool>();
624+
ISyncReport report = Substitute.For<ISyncReport>();
625+
report.HeadersInQueue.Returns(new MeasuredProgress());
626+
report.FastBlocksHeaders.Returns(new MeasuredProgress());
627+
using HeadersSyncFeed feed = new(localBlockTree, syncPeerPool, syncConfig, report, LimboLogs.Instance);
628+
feed.InitializeFeed();
629+
630+
(await feed.PrepareRequest()).Should().NotBe(null);
631+
(await feed.PrepareRequest()).Should().NotBe(null);
632+
(await feed.PrepareRequest()).Should().NotBe(null);
633+
}
634+
593635
[Test]
594636
public async Task Will_never_lose_batch_on_invalid_batch()
595637
{

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -488,15 +488,15 @@ private void EnqueueBatch(HeadersSyncBatch batch, bool skipPersisted = false)
488488
// This only check for the last header though, which is fine as headers are so small, the time it take
489489
// to download one is more or less the same as the whole batch. So many small batch is slower than
490490
// less large batch.
491-
BlockHeader? lastHeader = _blockTree.FindHeader(batch.EndNumber, BlockTreeLookupOptions.None);
491+
BlockHeader? lastHeader = _blockTree.FindHeader(batch.EndNumber, BlockTreeLookupOptions.TotalDifficultyNotNeeded);
492492
if (lastHeader is null) return batch;
493493

494494
using ArrayPoolList<BlockHeader> headers = new ArrayPoolList<BlockHeader>(1);
495495
headers.Add(lastHeader);
496496
for (long i = batch.EndNumber - 1; i >= batch.StartNumber; i--)
497497
{
498498
// Don't worry about fork, `InsertHeaders` will check for fork and retry if it is not on the right fork.
499-
BlockHeader nextHeader = _blockTree.FindHeader(lastHeader.ParentHash!, i);
499+
BlockHeader nextHeader = _blockTree.FindHeader(lastHeader.ParentHash!, BlockTreeLookupOptions.TotalDifficultyNotNeeded, i);
500500
if (nextHeader is null) break;
501501
headers.Add(nextHeader);
502502
lastHeader = nextHeader;

0 commit comments

Comments
 (0)