Skip to content

Commit d0d80d3

Browse files
authored
Merge pull request #1761 from 0chain/fix/check-nodes-at-initialisation
Check nodes health at initializing
2 parents 4523da7 + 5fb4ca9 commit d0d80d3

File tree

1 file changed

+90
-2
lines changed

1 file changed

+90
-2
lines changed

core/client/init_node.go

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,98 @@ func Init(ctx context.Context, cfg conf.Config) error {
136136
return err
137137
}
138138

139+
// Check if a node is online
140+
isNodeOnline := func(nodeURL string) bool {
141+
reqCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
142+
defer cancel()
143+
req, err := util.NewHTTPGetRequestContext(reqCtx, nodeURL)
144+
if err != nil {
145+
return false
146+
}
147+
res, err := req.Get()
148+
return err == nil && res.StatusCode == http.StatusOK
149+
}
150+
151+
// Filter online nodes concurrently
152+
filterOnlineNodes := func(nodes []string) []string {
153+
var onlineNodes []string
154+
var wg sync.WaitGroup
155+
var mu sync.Mutex
156+
157+
for _, node := range nodes {
158+
wg.Add(1)
159+
go func(url string) {
160+
defer wg.Done()
161+
if isNodeOnline(url) {
162+
mu.Lock()
163+
onlineNodes = append(onlineNodes, url)
164+
mu.Unlock()
165+
} else {
166+
logging.Debug("Node offline during initialization", zap.String("url", url))
167+
}
168+
}(node)
169+
}
170+
wg.Wait()
171+
return onlineNodes
172+
}
173+
174+
onlineMiners := filterOnlineNodes(network.Miners)
175+
onlineSharders := filterOnlineNodes(network.Sharders)
176+
139177
reqMiners := util.MaxInt(3, int(math.Ceil(float64(cfg.MinSubmit)*float64(len(network.Miners))/100)))
140-
sharders := NewHolder(network.Sharders, util.MinInt(len(network.Sharders), util.MaxInt(cfg.SharderConsensous, conf.DefaultSharderConsensous)))
178+
reqSharders := util.MinInt(len(network.Sharders), util.MaxInt(cfg.SharderConsensous, conf.DefaultSharderConsensous))
179+
180+
if len(onlineMiners) < reqMiners {
181+
logging.Debug("Not enough online miners found, supplementing with random miners",
182+
zap.Int("online", len(onlineMiners)),
183+
zap.Int("required", reqMiners))
184+
185+
onlineMinersMap := make(map[string]struct{})
186+
for _, miner := range onlineMiners {
187+
onlineMinersMap[miner] = struct{}{}
188+
}
189+
190+
offlineMiners := make([]string, 0)
191+
for _, miner := range network.Miners {
192+
if _, exists := onlineMinersMap[miner]; !exists {
193+
offlineMiners = append(offlineMiners, miner)
194+
}
195+
}
196+
197+
needed := reqMiners - len(onlineMiners)
198+
if needed > 0 && len(offlineMiners) > 0 {
199+
randomOfflineMiners := util.GetRandom(offlineMiners, needed)
200+
onlineMiners = append(onlineMiners, randomOfflineMiners...)
201+
}
202+
}
203+
204+
if len(onlineSharders) < reqSharders {
205+
logging.Debug("Not enough online sharders found, supplementing with random sharders",
206+
zap.Int("online", len(onlineSharders)),
207+
zap.Int("required", reqSharders))
208+
209+
onlineShardersMap := make(map[string]struct{})
210+
for _, sharder := range onlineSharders {
211+
onlineShardersMap[sharder] = struct{}{}
212+
}
213+
214+
offlineSharders := make([]string, 0)
215+
for _, sharder := range network.Sharders {
216+
if _, exists := onlineShardersMap[sharder]; !exists {
217+
offlineSharders = append(offlineSharders, sharder)
218+
}
219+
}
220+
221+
needed := reqSharders - len(onlineSharders)
222+
if needed > 0 && len(offlineSharders) > 0 {
223+
randomOfflineSharders := util.GetRandom(offlineSharders, needed)
224+
onlineSharders = append(onlineSharders, randomOfflineSharders...)
225+
}
226+
}
227+
228+
sharders := NewHolder(onlineSharders, reqSharders)
141229
nodeClient = &Node{
142-
stableMiners: util.GetRandom(network.Miners, reqMiners),
230+
stableMiners: onlineMiners,
143231
sharders: sharders,
144232
network: network,
145233
clientCtx: ctx,

0 commit comments

Comments
 (0)