github.com/theQRL/go-zond@v0.1.1/zond/catalyst/tester.go (about)

     1  // Copyright 2022 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package catalyst
    18  
    19  import (
    20  	"sync"
    21  	"time"
    22  
    23  	"github.com/theQRL/go-zond/core/types"
    24  	"github.com/theQRL/go-zond/log"
    25  	"github.com/theQRL/go-zond/node"
    26  	"github.com/theQRL/go-zond/zond"
    27  	"github.com/theQRL/go-zond/zond/downloader"
    28  )
    29  
    30  // FullSyncTester is an auxiliary service that allows Geth to perform full sync
    31  // alone without consensus-layer attached. Users must specify a valid block as
    32  // the sync target. This tester can be applied to different networks, no matter
    33  // it's pre-merge or post-merge, but only for full-sync.
    34  type FullSyncTester struct {
    35  	api    *ConsensusAPI
    36  	block  *types.Block
    37  	closed chan struct{}
    38  	wg     sync.WaitGroup
    39  }
    40  
    41  // RegisterFullSyncTester registers the full-sync tester service into the node
    42  // stack for launching and stopping the service controlled by node.
    43  func RegisterFullSyncTester(stack *node.Node, backend *zond.Ethereum, block *types.Block) (*FullSyncTester, error) {
    44  	cl := &FullSyncTester{
    45  		api:    newConsensusAPIWithoutHeartbeat(backend),
    46  		block:  block,
    47  		closed: make(chan struct{}),
    48  	}
    49  	stack.RegisterLifecycle(cl)
    50  	return cl, nil
    51  }
    52  
    53  // Start launches the beacon sync with provided sync target.
    54  func (tester *FullSyncTester) Start() error {
    55  	tester.wg.Add(1)
    56  	go func() {
    57  		defer tester.wg.Done()
    58  
    59  		ticker := time.NewTicker(time.Second * 5)
    60  		defer ticker.Stop()
    61  
    62  		for {
    63  			select {
    64  			case <-ticker.C:
    65  				// Don't bother downloader in case it's already syncing.
    66  				if tester.api.eth.Downloader().Synchronising() {
    67  					continue
    68  				}
    69  				// Short circuit in case the target block is already stored
    70  				// locally. TODO(somehow terminate the node stack if target
    71  				// is reached).
    72  				if tester.api.eth.BlockChain().HasBlock(tester.block.Hash(), tester.block.NumberU64()) {
    73  					log.Info("Full-sync target reached", "number", tester.block.NumberU64(), "hash", tester.block.Hash())
    74  					return
    75  				}
    76  				// Trigger beacon sync with the provided block header as
    77  				// trusted chain head.
    78  				err := tester.api.eth.Downloader().BeaconSync(downloader.FullSync, tester.block.Header(), tester.block.Header())
    79  				if err != nil {
    80  					log.Info("Failed to beacon sync", "err", err)
    81  				}
    82  
    83  			case <-tester.closed:
    84  				return
    85  			}
    86  		}
    87  	}()
    88  	return nil
    89  }
    90  
    91  // Stop stops the full-sync tester to stop all background activities.
    92  // This function can only be called for one time.
    93  func (tester *FullSyncTester) Stop() error {
    94  	close(tester.closed)
    95  	tester.wg.Wait()
    96  	return nil
    97  }