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  }