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 }