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 }