// Copyright 2015 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . package eth import ( "testing" "time" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/enode" ) // Tests that snap sync is disabled after a successful sync cycle. func TestSnapSyncDisabling68(t *testing.T) { testSnapSyncDisabling(t, eth.ETH68, snap.SNAP1) } // Tests that snap sync gets disabled as soon as a real block is successfully // imported into the blockchain. func testSnapSyncDisabling(t *testing.T, ethVer uint, snapVer uint) { t.Parallel() // Create an empty handler and ensure it's in snap sync mode empty := newTestHandler(ethconfig.SnapSync) defer empty.close() // Create a full handler and ensure snap sync ends up disabled full := newTestHandlerWithBlocks(1024, ethconfig.SnapSync) defer full.close() // Sync up the two handlers via both `eth` and `snap` caps := []p2p.Cap{{Name: "eth", Version: ethVer}, {Name: "snap", Version: snapVer}} emptyPipeEth, fullPipeEth := p2p.MsgPipe() defer emptyPipeEth.Close() defer fullPipeEth.Close() emptyPeerEth := eth.NewPeer(ethVer, p2p.NewPeer(enode.ID{1}, "", caps), emptyPipeEth, empty.txpool) fullPeerEth := eth.NewPeer(ethVer, p2p.NewPeer(enode.ID{2}, "", caps), fullPipeEth, full.txpool) defer emptyPeerEth.Close() defer fullPeerEth.Close() go empty.handler.runEthPeer(emptyPeerEth, func(peer *eth.Peer) error { return eth.Handle((*ethHandler)(empty.handler), peer) }) go full.handler.runEthPeer(fullPeerEth, func(peer *eth.Peer) error { return eth.Handle((*ethHandler)(full.handler), peer) }) emptyPipeSnap, fullPipeSnap := p2p.MsgPipe() defer emptyPipeSnap.Close() defer fullPipeSnap.Close() emptyPeerSnap := snap.NewPeer(snapVer, p2p.NewPeer(enode.ID{1}, "", caps), emptyPipeSnap) fullPeerSnap := snap.NewPeer(snapVer, p2p.NewPeer(enode.ID{2}, "", caps), fullPipeSnap) go empty.handler.runSnapExtension(emptyPeerSnap, func(peer *snap.Peer) error { return snap.Handle((*snapHandler)(empty.handler), peer) }) go full.handler.runSnapExtension(fullPeerSnap, func(peer *snap.Peer) error { return snap.Handle((*snapHandler)(full.handler), peer) }) // Wait a bit for the above handlers to start time.Sleep(250 * time.Millisecond) // Check that snap sync was disabled if err := empty.handler.downloader.BeaconSync(full.chain.CurrentBlock(), nil); err != nil { t.Fatal("sync failed:", err) } // Downloader internally has to wait for a timer (3s) to be expired before // exiting. Poll after to determine if sync is disabled. time.Sleep(time.Second * 3) for timeout := time.After(time.Second); ; { select { case <-timeout: t.Fatalf("snap sync not disabled after successful synchronisation") case <-time.After(100 * time.Millisecond): if empty.handler.downloader.ConfigSyncMode() == ethconfig.FullSync { return } } } }