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

     1  //go:build !mobile
     2  // +build !mobile
     3  
     4  package zcncore
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  	"net/http"
    10  	"reflect"
    11  	"time"
    12  
    13  	"github.com/0chain/errors"
    14  	"github.com/0chain/gosdk/core/conf"
    15  	"github.com/0chain/gosdk/core/node"
    16  	"github.com/0chain/gosdk/core/util"
    17  	"go.uber.org/zap"
    18  )
    19  
    20  const NETWORK_ENDPOINT = "/network"
    21  
    22  var networkWorkerTimerInHours = 1
    23  
    24  // Network details of the network nodes
    25  type Network struct {
    26  	Miners   []string `json:"miners"`
    27  	Sharders []string `json:"sharders"`
    28  }
    29  
    30  func updateNetworkDetailsWorker(ctx context.Context) {
    31  	ticker := time.NewTicker(time.Duration(networkWorkerTimerInHours) * time.Hour)
    32  	for {
    33  		select {
    34  		case <-ctx.Done():
    35  			logging.Info("Network stopped by user")
    36  			return
    37  		case <-ticker.C:
    38  			err := UpdateNetworkDetails()
    39  			if err != nil {
    40  				logging.Error("Update network detail worker fail", zap.Error(err))
    41  				return
    42  			}
    43  			logging.Info("Successfully updated network details")
    44  			return
    45  		}
    46  	}
    47  }
    48  
    49  func UpdateNetworkDetails() error {
    50  	networkDetails, err := GetNetworkDetails()
    51  	if err != nil {
    52  		logging.Error("Failed to update network details ", zap.Error(err))
    53  		return err
    54  	}
    55  
    56  	shouldUpdate := UpdateRequired(networkDetails)
    57  	if shouldUpdate {
    58  		_config.isConfigured = false
    59  		_config.chain.Miners = networkDetails.Miners
    60  		_config.chain.Sharders = networkDetails.Sharders
    61  		consensus := _config.chain.SharderConsensous
    62  		if consensus < conf.DefaultSharderConsensous {
    63  			consensus = conf.DefaultSharderConsensous
    64  		}
    65  		if len(networkDetails.Sharders) < consensus {
    66  			consensus = len(networkDetails.Sharders)
    67  		}
    68  
    69  		Sharders = node.NewHolder(networkDetails.Sharders, consensus)
    70  		node.InitCache(Sharders)
    71  		conf.InitChainNetwork(&conf.Network{
    72  			Sharders: networkDetails.Sharders,
    73  			Miners:   networkDetails.Miners,
    74  		})
    75  		_config.isConfigured = true
    76  	}
    77  	return nil
    78  }
    79  
    80  func UpdateRequired(networkDetails *Network) bool {
    81  	miners := _config.chain.Miners
    82  	sharders := _config.chain.Sharders
    83  	if len(miners) == 0 || len(sharders) == 0 {
    84  		return true
    85  	}
    86  
    87  	minerSame := reflect.DeepEqual(miners, networkDetails.Miners)
    88  	sharderSame := reflect.DeepEqual(sharders, networkDetails.Sharders)
    89  
    90  	if minerSame && sharderSame {
    91  		return false
    92  	}
    93  	return true
    94  }
    95  
    96  func GetNetworkDetails() (*Network, error) {
    97  	req, err := util.NewHTTPGetRequest(_config.chain.BlockWorker + NETWORK_ENDPOINT)
    98  	if err != nil {
    99  		return nil, errors.New("get_network_details_error", "Unable to create new http request with error "+err.Error())
   100  	}
   101  
   102  	res, err := req.Get()
   103  	if err != nil {
   104  		return nil, errors.New("get_network_details_error", "Unable to get http request with error "+err.Error())
   105  	}
   106  
   107  	if res.StatusCode != http.StatusOK {
   108  		return nil, errors.New("get_network_details_error", "Unable to get http request with "+res.Status)
   109  
   110  	}
   111  	var networkResponse Network
   112  	err = json.Unmarshal([]byte(res.Body), &networkResponse)
   113  	if err != nil {
   114  		return nil, errors.Wrap(err, "Error unmarshaling response :"+res.Body)
   115  	}
   116  	return &networkResponse, nil
   117  
   118  }
   119  
   120  // GetNetwork retrieve the registered network details.
   121  func GetNetwork() *Network {
   122  	return &Network{
   123  		Miners:   _config.chain.Miners,
   124  		Sharders: _config.chain.Sharders,
   125  	}
   126  }
   127  
   128  // SetNetwork set the global network details for the SDK, including urls of the miners and sharders, which are the nodes of the network.
   129  //   - miners: miner urls.
   130  //   - sharders: sharder urls.
   131  func SetNetwork(miners []string, sharders []string) {
   132  	_config.chain.Miners = miners
   133  	_config.chain.Sharders = sharders
   134  
   135  	consensus := _config.chain.SharderConsensous
   136  	if consensus < conf.DefaultSharderConsensous {
   137  		consensus = conf.DefaultSharderConsensous
   138  	}
   139  	if len(sharders) < consensus {
   140  		consensus = len(sharders)
   141  	}
   142  
   143  	Sharders = node.NewHolder(sharders, consensus)
   144  	node.InitCache(Sharders)
   145  
   146  	conf.InitChainNetwork(&conf.Network{
   147  		Miners:   miners,
   148  		Sharders: sharders,
   149  	})
   150  }
   151  
   152  // GetNetworkJSON retrieve the registered network details in JSON format.
   153  func GetNetworkJSON() string {
   154  	network := GetNetwork()
   155  	networkBytes, _ := json.Marshal(network)
   156  	return string(networkBytes)
   157  }