eth/downloader: lift broken test-case from post-merge cleanup PR.

This commit is contained in:
Jared Wasinger 2024-03-26 17:17:14 -07:00
parent bd91810462
commit 6986095f81
2 changed files with 100 additions and 1 deletions

View file

@ -1311,3 +1311,97 @@ func testBeaconSync(t *testing.T, protocol uint, mode SyncMode) {
}) })
} }
} }
// Tests that synchronisation progress (origin block number and highest block
// number) is tracked and updated correctly in case of manual head reversion
func TestBeaconForkedSyncProgress68Full(t *testing.T) {
testBeaconForkedSyncProgress(t, eth.ETH68, FullSync)
}
func TestBeaconForkedSyncProgress68Snap(t *testing.T) {
testBeaconForkedSyncProgress(t, eth.ETH68, SnapSync)
}
func TestBeaconForkedSyncProgress68Light(t *testing.T) {
testBeaconForkedSyncProgress(t, eth.ETH68, LightSync)
}
func testBeaconForkedSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
success := make(chan struct{})
tester := newTesterWithNotification(t, func() {
success <- struct{}{}
})
defer tester.terminate()
chainA := testChainForkLightA.shorten(len(testChainBase.blocks) + MaxHeaderFetch)
chainB := testChainForkHigher.shorten(len(testChainBase.blocks) + MaxHeaderFetch)
// Set a sync init hook to catch progress changes
starting := make(chan struct{})
progress := make(chan struct{})
tester.downloader.syncInitHook = func(origin, latest uint64) {
fmt.Println("sync init")
starting <- struct{}{}
<-progress
}
checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{})
// Synchronise with one of the forks and check progress
tester.newPeer("fork A", protocol, chainA.blocks[1:])
pending := new(sync.WaitGroup)
pending.Add(1)
go func() {
defer pending.Done()
if err := tester.downloader.BeaconSync(mode, chainA.blocks[len(chainA.blocks)-1].Header(), nil); err != nil {
panic(fmt.Sprintf("failed to beacon sync: %v", err))
}
}()
<-starting
progress <- struct{}{}
select {
case <-success:
checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{
HighestBlock: uint64(len(chainA.blocks) - 1),
CurrentBlock: uint64(len(chainA.blocks) - 1),
})
case <-time.NewTimer(time.Second * 3).C:
t.Fatalf("Failed to sync chain in three seconds")
}
fmt.Println("jump in")
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stdout, log.LevelInfo, false)))
// Set the head to a second fork (which forks after the origin of the last sync cycle
tester.newPeer("fork B", protocol, chainB.blocks[1:])
pending.Add(1)
go func() {
defer pending.Done()
if err := tester.downloader.BeaconSync(mode, chainB.blocks[len(chainB.blocks)-1].Header(), nil); err != nil {
panic(fmt.Sprintf("failed to beacon sync: %v", err))
}
}()
select {
case <-success:
checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{
HighestBlock: uint64(len(chainB.blocks) - 1),
CurrentBlock: uint64(len(chainB.blocks) - 1),
// TODO: check that origin block is at the start of the fork (not 0)
})
case <-time.NewTimer(time.Second * 3).C:
t.Fatalf("Failed to sync chain in three seconds")
}
checkProgress(t, tester.downloader, "forking", ethereum.SyncProgress{
StartingBlock: uint64(len(testChainBase.blocks)) - 1,
CurrentBlock: uint64(len(chainA.blocks) - 1),
HighestBlock: uint64(len(chainB.blocks) - 1),
})
// Check final progress after successful sync
progress <- struct{}{}
pending.Wait()
checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{
StartingBlock: uint64(len(testChainBase.blocks)) - 1,
CurrentBlock: uint64(len(chainB.blocks) - 1),
HighestBlock: uint64(len(chainB.blocks) - 1),
})
}

View file

@ -53,6 +53,9 @@ var testChainBase *testChain
// Different forks on top of the base chain: // Different forks on top of the base chain:
var testChainForkLightA, testChainForkLightB, testChainForkHeavy *testChain var testChainForkLightA, testChainForkLightB, testChainForkHeavy *testChain
// Fork from base chain, fork occurs 10 blocks later than other forks
var testChainForkHigher *testChain
var pregenerated bool var pregenerated bool
func init() { func init() {
@ -69,10 +72,11 @@ func init() {
var wg sync.WaitGroup var wg sync.WaitGroup
// Generate the test chains to seed the peers with // Generate the test chains to seed the peers with
wg.Add(3) wg.Add(4)
go func() { testChainForkLightA = testChainBase.makeFork(forkLen, false, 1); wg.Done() }() go func() { testChainForkLightA = testChainBase.makeFork(forkLen, false, 1); wg.Done() }()
go func() { testChainForkLightB = testChainBase.makeFork(forkLen, false, 2); wg.Done() }() go func() { testChainForkLightB = testChainBase.makeFork(forkLen, false, 2); wg.Done() }()
go func() { testChainForkHeavy = testChainBase.makeFork(forkLen, true, 3); wg.Done() }() go func() { testChainForkHeavy = testChainBase.makeFork(forkLen, true, 3); wg.Done() }()
go func() { testChainForkHigher = testChainBase.makeFork(forkLen-10, false, 3); wg.Done() }()
wg.Wait() wg.Wait()
// Generate the test peers used by the tests to avoid overloading during testing. // Generate the test peers used by the tests to avoid overloading during testing.
@ -103,6 +107,7 @@ func init() {
testChainForkLightA.shorten(len(testChainBase.blocks) + MaxHeaderFetch), testChainForkLightA.shorten(len(testChainBase.blocks) + MaxHeaderFetch),
testChainForkLightB.shorten(len(testChainBase.blocks) + MaxHeaderFetch), testChainForkLightB.shorten(len(testChainBase.blocks) + MaxHeaderFetch),
testChainForkHeavy.shorten(len(testChainBase.blocks) + 79), testChainForkHeavy.shorten(len(testChainBase.blocks) + 79),
testChainForkHigher.shorten(len(testChainBase.blocks) + MaxHeaderFetch),
} }
wg.Add(len(chains)) wg.Add(len(chains))
for _, chain := range chains { for _, chain := range chains {