github.com/theQRL/go-zond@v0.2.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/common"
    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 hash
    32  // as the sync target.
    33  //
    34  // This tester can be only be applied for full-sync.
    35  type FullSyncTester struct {
    36  	stack   *node.Node
    37  	backend *zond.Zond
    38  	target  common.Hash
    39  	closed  chan struct{}
    40  	wg      sync.WaitGroup
    41  }
    42  
    43  // RegisterFullSyncTester registers the full-sync tester service into the node
    44  // stack for launching and stopping the service controlled by node.
    45  func RegisterFullSyncTester(stack *node.Node, backend *zond.Zond, target common.Hash) (*FullSyncTester, error) {
    46  	cl := &FullSyncTester{
    47  		stack:   stack,
    48  		backend: backend,
    49  		target:  target,
    50  		closed:  make(chan struct{}),
    51  	}
    52  	stack.RegisterLifecycle(cl)
    53  	return cl, nil
    54  }
    55  
    56  // Start launches the beacon sync with provided sync target.
    57  func (tester *FullSyncTester) Start() error {
    58  	tester.wg.Add(1)
    59  	go func() {
    60  		defer tester.wg.Done()
    61  
    62  		// Trigger beacon sync with the provided block hash as trusted
    63  		// chain head.
    64  		err := tester.backend.Downloader().BeaconDevSync(downloader.FullSync, tester.target, tester.closed)
    65  		if err != nil {
    66  			log.Info("Failed to trigger beacon sync", "err", err)
    67  		}
    68  
    69  		ticker := time.NewTicker(time.Second * 5)
    70  		defer ticker.Stop()
    71  
    72  		for {
    73  			select {
    74  			case <-ticker.C:
    75  				// Stop in case the target block is already stored locally.
    76  				if block := tester.backend.BlockChain().GetBlockByHash(tester.target); block != nil {
    77  					log.Info("Full-sync target reached", "number", block.NumberU64(), "hash", block.Hash())
    78  					go tester.stack.Close() // async since we need to close ourselves
    79  					return
    80  				}
    81  
    82  			case <-tester.closed:
    83  				return
    84  			}
    85  		}
    86  	}()
    87  	return nil
    88  }
    89  
    90  // Stop stops the full-sync tester to stop all background activities.
    91  // This function can only be called for one time.
    92  func (tester *FullSyncTester) Stop() error {
    93  	close(tester.closed)
    94  	tester.wg.Wait()
    95  	return nil
    96  }