github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/blockproc/verwatcher/version_watcher.go (about) 1 package verwatcher 2 3 import ( 4 "fmt" 5 "math/big" 6 "sync" 7 "time" 8 9 "github.com/unicornultrafoundation/go-u2u/core/types" 10 11 "github.com/unicornultrafoundation/go-u2u/logger" 12 "github.com/unicornultrafoundation/go-u2u/u2u/contracts/driver" 13 "github.com/unicornultrafoundation/go-u2u/u2u/contracts/driver/driverpos" 14 "github.com/unicornultrafoundation/go-u2u/version" 15 ) 16 17 type VerWarcher struct { 18 store *Store 19 20 done chan struct{} 21 wg sync.WaitGroup 22 logger.Instance 23 } 24 25 func New(store *Store) *VerWarcher { 26 return &VerWarcher{ 27 store: store, 28 done: make(chan struct{}), 29 Instance: logger.New(), 30 } 31 } 32 33 func (w *VerWarcher) Pause() error { 34 if w.store.GetNetworkVersion() > version.AsU64() { 35 return fmt.Errorf("Network upgrade %s was activated. Current node version is %s. "+ 36 "Please upgrade your node to continue syncing.", version.U64ToString(w.store.GetNetworkVersion()), version.AsString()) 37 } else if w.store.GetMissedVersion() > 0 { 38 return fmt.Errorf("Node's state is dirty because node was upgraded after the network upgrade %s was activated. "+ 39 "Please re-sync the chain data to continue.", version.U64ToString(w.store.GetMissedVersion())) 40 } 41 return nil 42 } 43 44 func (w *VerWarcher) OnNewLog(l *types.Log) { 45 if l.Address != driver.ContractAddress { 46 return 47 } 48 if l.Topics[0] == driverpos.Topics.UpdateNetworkVersion && len(l.Data) >= 32 { 49 netVersion := new(big.Int).SetBytes(l.Data[24:32]).Uint64() 50 w.store.SetNetworkVersion(netVersion) 51 w.log() 52 } 53 } 54 55 func (w *VerWarcher) log() { 56 if err := w.Pause(); err != nil { 57 w.Log.Warn(err.Error()) 58 } 59 } 60 61 func (w *VerWarcher) Start() { 62 w.log() 63 w.wg.Add(1) 64 go func() { 65 defer w.wg.Done() 66 ticker := time.NewTicker(time.Second) 67 defer ticker.Stop() 68 for { 69 select { 70 case <-ticker.C: 71 w.log() 72 case <-w.done: 73 return 74 } 75 } 76 }() 77 } 78 79 func (w *VerWarcher) Stop() { 80 close(w.done) 81 w.wg.Wait() 82 }