github.com/0chain/gosdk@v1.17.11/zboxcore/sdk/networkworker.go (about)

     1  package sdk
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"reflect"
     9  	"strconv"
    10  	"time"
    11  
    12  	"github.com/0chain/gosdk/core/node"
    13  	l "github.com/0chain/gosdk/zboxcore/logger"
    14  	"go.uber.org/zap"
    15  
    16  	"github.com/0chain/errors"
    17  	"github.com/0chain/gosdk/core/conf"
    18  	"github.com/0chain/gosdk/zboxcore/blockchain"
    19  	"github.com/0chain/gosdk/zboxcore/zboxutil"
    20  )
    21  
    22  const NETWORK_ENDPOINT = "/network"
    23  
    24  type Network struct {
    25  	Miners   []string `json:"miners"`
    26  	Sharders []string `json:"sharders"`
    27  }
    28  
    29  func UpdateNetworkDetailsWorker(ctx context.Context) {
    30  	ticker := time.NewTicker(time.Duration(networkWorkerTimerInHours) * time.Hour)
    31  	for {
    32  		select {
    33  		case <-ctx.Done():
    34  			l.Logger.Info("Network stopped by user")
    35  			return
    36  		case <-ticker.C:
    37  			err := UpdateNetworkDetails()
    38  			if err != nil {
    39  				l.Logger.Error("Update network detail worker fail", zap.Error(err))
    40  				return
    41  			}
    42  			l.Logger.Info("Successfully updated network details")
    43  			return
    44  		}
    45  	}
    46  }
    47  
    48  func UpdateNetworkDetails() error {
    49  	networkDetails, err := GetNetworkDetails()
    50  	if err != nil {
    51  		l.Logger.Error("Failed to update network details ", zap.Error(err))
    52  		return err
    53  	}
    54  
    55  	shouldUpdate := UpdateRequired(networkDetails)
    56  	if shouldUpdate {
    57  		forceUpdateNetworkDetails(networkDetails)
    58  	}
    59  	return nil
    60  }
    61  
    62  func InitNetworkDetails() error {
    63  	networkDetails, err := GetNetworkDetails()
    64  	if err != nil {
    65  		l.Logger.Error("Failed to update network details ", zap.Error(err))
    66  		return err
    67  	}
    68  	forceUpdateNetworkDetails(networkDetails)
    69  	return nil
    70  }
    71  
    72  func forceUpdateNetworkDetails(networkDetails *Network) {
    73  	sdkInitialized = false
    74  	blockchain.SetMiners(networkDetails.Miners)
    75  	blockchain.SetSharders(networkDetails.Sharders)
    76  	node.InitCache(blockchain.Sharders)
    77  	conf.InitChainNetwork(&conf.Network{
    78  		Sharders: networkDetails.Sharders,
    79  		Miners:   networkDetails.Miners,
    80  	})
    81  	sdkInitialized = true
    82  }
    83  
    84  func UpdateRequired(networkDetails *Network) bool {
    85  	miners := blockchain.GetMiners()
    86  	sharders := blockchain.GetAllSharders()
    87  	if len(miners) == 0 || len(sharders) == 0 {
    88  		return true
    89  	}
    90  
    91  	minerSame := reflect.DeepEqual(miners, networkDetails.Miners)
    92  	sharderSame := reflect.DeepEqual(sharders, networkDetails.Sharders)
    93  
    94  	if minerSame && sharderSame {
    95  		return false
    96  	}
    97  	return true
    98  }
    99  
   100  func GetNetworkDetails() (*Network, error) {
   101  	req, ctx, cncl, err := zboxutil.NewHTTPRequest(http.MethodGet, blockchain.GetBlockWorker()+NETWORK_ENDPOINT, nil)
   102  	if err != nil {
   103  		return nil, errors.New("get_network_details_error", "Unable to create new http request with error "+err.Error())
   104  	}
   105  
   106  	var networkResponse Network
   107  	err = zboxutil.HttpDo(ctx, cncl, req, func(resp *http.Response, err error) error {
   108  		if err != nil {
   109  			l.Logger.Error("Get network error : ", err)
   110  			return err
   111  		}
   112  
   113  		defer resp.Body.Close()
   114  		respBody, err := ioutil.ReadAll(resp.Body)
   115  		if err != nil {
   116  			return errors.Wrap(err, "Error reading response : ")
   117  		}
   118  
   119  		l.Logger.Debug("Get network result:", string(respBody))
   120  		if resp.StatusCode == http.StatusOK {
   121  			err = json.Unmarshal(respBody, &networkResponse)
   122  			if err != nil {
   123  				return errors.Wrap(err, "Error unmarshaling response :")
   124  			}
   125  			return nil
   126  		}
   127  		return errors.New(strconv.Itoa(resp.StatusCode), "Get network details status not OK")
   128  
   129  	})
   130  	return &networkResponse, err
   131  }