Skip to content

Commit

Permalink
Fix next header hash may be mis-set. (#5112)
Browse files Browse the repository at this point in the history
  • Loading branch information
asdacap authored Jan 9, 2023
1 parent ef5ebfc commit 2c363ba
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,25 @@ public async Task Finishes_when_all_downloaded()
measuredProgress.HasEnded.Should().BeTrue();
}

[Test]
public async Task Can_resume_downloading_from_parent_of_lowest_inserted_header()
{
IBlockTree blockTree = Substitute.For<IBlockTree>();
blockTree.LowestInsertedHeader.Returns(Build.A.BlockHeader
.WithNumber(500)
.WithTotalDifficulty(10_000_000)
.TestObject);

ISyncReport report = Substitute.For<ISyncReport>();
report.HeadersInQueue.Returns(new MeasuredProgress());
report.FastBlocksHeaders.Returns(new MeasuredProgress());

HeadersSyncFeed feed = new(Substitute.For<ISyncModeSelector>(), blockTree, Substitute.For<ISyncPeerPool>(), new SyncConfig { FastSync = true, FastBlocks = true, PivotNumber = "1000", PivotHash = Keccak.Zero.ToString(), PivotTotalDifficulty = "1000" }, report, LimboLogs.Instance);
feed.InitializeFeed();
var result = await feed.PrepareRequest();
result.EndNumber.Should().Be(499);
}

private class ResettableHeaderSyncFeed : HeadersSyncFeed
{
public ResettableHeaderSyncFeed(ISyncModeSelector syncModeSelector, IBlockTree? blockTree, ISyncPeerPool? syncPeerPool, ISyncConfig? syncConfig, ISyncReport? syncReport, ILogManager? logManager, bool alwaysStartHeaderSync = false) : base(syncModeSelector, blockTree, syncPeerPool, syncConfig, syncReport, logManager, alwaysStartHeaderSync)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,18 +183,20 @@ public HeadersSyncFeed(

public override void InitializeFeed()
{
_logger.Info("Feed reinitialized");
_pivotNumber = _syncConfig.PivotNumberParsed;

bool useSyncPivot = _blockTree.LowestInsertedHeader is null || _blockTree.LowestInsertedHeader.Number > _pivotNumber;
BlockHeader? lowestInserted = _blockTree.LowestInsertedHeader;
long startNumber = useSyncPivot ? _pivotNumber : lowestInserted.Number;
Keccak startHeaderHash = useSyncPivot ? _syncConfig.PivotHashParsed : lowestInserted.Hash;
UInt256? startTotalDifficulty = useSyncPivot ? _syncConfig.PivotTotalDifficultyParsed : lowestInserted?.TotalDifficulty;

_nextHeaderHash = startHeaderHash;
_nextHeaderDiff = startTotalDifficulty;
_lowestRequestedHeaderNumber = _pivotNumber + 1; // Because we want the pivot to be requested
_nextHeaderHash = _syncConfig.PivotHashParsed;
_nextHeaderDiff = _syncConfig.PivotTotalDifficultyParsed;

_lowestRequestedHeaderNumber = startNumber + 1;
// Resume logic
BlockHeader? lowestInserted = _blockTree.LowestInsertedHeader;
if (lowestInserted != null && lowestInserted!.Number < _pivotNumber)
{
SetExpectedNextHeaderToParent(lowestInserted);
_lowestRequestedHeaderNumber = lowestInserted.Number;
}

base.InitializeFeed();
}
Expand Down Expand Up @@ -652,19 +654,24 @@ protected virtual AddBlockResult InsertToBlockTree(BlockHeader header)
AddBlockResult insertOutcome = _blockTree.Insert(header);
if (insertOutcome == AddBlockResult.Added || insertOutcome == AddBlockResult.AlreadyKnown)
{
ulong nextHeaderDiff = 0;
_nextHeaderHash = header.ParentHash!;
if (_expectedDifficultyOverride?.TryGetValue(header.Number, out nextHeaderDiff) == true)
{
_nextHeaderDiff = nextHeaderDiff;
}
else
{
_nextHeaderDiff = (header.TotalDifficulty ?? 0) - header.Difficulty;
}
SetExpectedNextHeaderToParent(header);
}

return insertOutcome;
}

private void SetExpectedNextHeaderToParent(BlockHeader header)
{
ulong nextHeaderDiff = 0;
_nextHeaderHash = header.ParentHash!;
if (_expectedDifficultyOverride?.TryGetValue(header.Number, out nextHeaderDiff) == true)
{
_nextHeaderDiff = nextHeaderDiff;
}
else
{
_nextHeaderDiff = (header.TotalDifficulty ?? 0) - header.Difficulty;
}
}
}
}

0 comments on commit 2c363ba

Please sign in to comment.