github.com/annchain/OG@v0.0.9/og/syncer/syncer_manager.go (about)

     1  // Copyright © 2019 Annchain Authors <EMAIL ADDRESS>
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package syncer
    15  
    16  import (
    17  	"github.com/annchain/OG/arefactor/common/goroutine"
    18  	"github.com/annchain/OG/og"
    19  	"github.com/annchain/OG/og/downloader"
    20  )
    21  
    22  type SyncManagerConfig struct {
    23  	Mode           downloader.SyncMode
    24  	BootstrapNode  bool
    25  	ForceSyncCycle uint //milliseconds
    26  }
    27  
    28  type SyncStatus int
    29  
    30  const (
    31  	SyncStatusIncremental SyncStatus = iota
    32  	SyncStatusFull
    33  )
    34  
    35  func (m SyncStatus) String() string {
    36  	switch m {
    37  	case SyncStatusIncremental:
    38  		return "SyncStatusIncremental"
    39  	case SyncStatusFull:
    40  		return "SyncStatusFull"
    41  	default:
    42  		return "Default"
    43  	}
    44  }
    45  
    46  type SyncManager struct {
    47  	Hub                    *og.Hub
    48  	CatchupSyncer          *CatchupSyncer
    49  	IncrementalSyncer      *IncrementalSyncer
    50  	NodeStatusDataProvider og.NodeStatusDataProvider
    51  
    52  	OnUpToDate []chan bool // listeners registered for enabling/disabling generating and receiving txs (fully synced or not)
    53  
    54  	// moved from hub to here.
    55  	//fastSync  uint32 // Flag whether fast sync is enabled (gets disabled if we already have blocks)
    56  	//acceptTxs uint32 // Flag whether we're considered synchronised (enables transaction processing)
    57  
    58  	//forceSyncCycle uint
    59  	//syncFlag       uint32 //1 for is syncing
    60  	BootstrapNode                    bool //if bootstrap node just accept txs in starting ,no sync
    61  	CatchupSyncerWorkingStateChanged chan CatchupSyncerStatus
    62  	quitFlag                         bool
    63  	Status                           SyncStatus
    64  
    65  	//OnNewTxiReceived []chan types.Txi	// for both incremental tx and catchup tx
    66  }
    67  
    68  func (s *SyncManager) GetBenchmarks() map[string]interface{} {
    69  	return map[string]interface{}{}
    70  }
    71  
    72  func (s *SyncManager) Start() {
    73  	// start full sync listener
    74  
    75  	// start incremental sync listener
    76  	// start tx announcement
    77  	// short cut. make it formal later
    78  	//s.CatchupSyncer.OnNewTxiReceived = s.OnNewTxiReceived
    79  	//s.IncrementalSyncer.OnNewTxiReceived = s.OnNewTxiReceived
    80  	s.CatchupSyncer.OnWorkingStateChanged = append(s.CatchupSyncer.OnWorkingStateChanged, s.CatchupSyncerWorkingStateChanged)
    81  
    82  	s.CatchupSyncer.Start()
    83  	s.IncrementalSyncer.Start()
    84  	goroutine.New(s.loopSync)
    85  	goroutine.New(
    86  		func() {
    87  			// if BootstrapNode  just accept txs
    88  			if s.BootstrapNode {
    89  				s.CatchupSyncer.NotifyWorkingStateChanged(Stopped, false)
    90  			} else {
    91  				//default if false ' don't send again
    92  				//s.NotifyUpToDateEvent(false)
    93  			}
    94  		})
    95  }
    96  
    97  func (s *SyncManager) Stop() {
    98  	s.quitFlag = true
    99  }
   100  
   101  func (s *SyncManager) Name() string {
   102  	return "SyncManager"
   103  }
   104  
   105  func NewSyncManager(config SyncManagerConfig, hub *og.Hub, NodeStatusDataProvider og.NodeStatusDataProvider) *SyncManager {
   106  	sm := &SyncManager{
   107  		Hub:                              hub,
   108  		NodeStatusDataProvider:           NodeStatusDataProvider,
   109  		CatchupSyncerWorkingStateChanged: make(chan CatchupSyncerStatus),
   110  		BootstrapNode:                    config.BootstrapNode,
   111  	}
   112  
   113  	// Figure out whether to allow fast sync or not
   114  	if config.Mode == downloader.FastSync && sm.NodeStatusDataProvider.GetCurrentNodeStatus().CurrentId > 0 {
   115  		log.Warn("dag not empty, fast sync disabled")
   116  		config.Mode = downloader.FullSync
   117  	}
   118  	if config.Mode == downloader.FastSync {
   119  		//sm.fastSync = uint32(1)
   120  	}
   121  	//sm.forceSyncCycle = config.ForceSyncCycle
   122  	return sm
   123  }
   124  
   125  // loopSync constantly check if there is new peer connected
   126  func (s *SyncManager) loopSync() {
   127  	s.IncrementalSyncer.EnableEvent <- false
   128  	s.CatchupSyncer.EnableEvent <- true
   129  	// <-ffchan.NewTimeoutSender(s.IncrementalSyncer.EnableEvent, false, "timeoutAcquireTx", 1000).C
   130  	// <-ffchan.NewTimeoutSender(s.CatchupSyncer.EnableEvent, true, "timeoutAcquireTx", 1000).C
   131  
   132  	s.Status = SyncStatusFull
   133  
   134  	for !s.quitFlag {
   135  		// listen to either full sync or incremental sync to get something new.
   136  		select {
   137  		case status := <-s.CatchupSyncerWorkingStateChanged:
   138  			log.WithField("v", status.String()).Info("catchup syncer working state changed")
   139  			switch status {
   140  			case Started:
   141  				// catch up started. pause incremental
   142  				s.Status = SyncStatusFull
   143  				s.IncrementalSyncer.EnableEvent <- false
   144  				// <-ffchan.NewTimeoutSender(s.IncrementalSyncer.EnableEvent, false, "IncrementalSyncerEnable", 1000).C
   145  				s.NotifyUpToDateEvent(false)
   146  			case Stopped:
   147  				// catch up already done. now it is up to date. start incremental
   148  				s.Status = SyncStatusIncremental
   149  				s.IncrementalSyncer.EnableEvent <- true
   150  				// <-ffchan.NewTimeoutSender(s.IncrementalSyncer.EnableEvent, true, "IncrementalSyncerEnable", 1000).C
   151  				s.NotifyUpToDateEvent(true)
   152  			}
   153  		}
   154  	}
   155  }
   156  
   157  func (s *SyncManager) NotifyUpToDateEvent(isUpToDate bool) {
   158  	for _, c := range s.OnUpToDate {
   159  		c <- isUpToDate
   160  	}
   161  }