@@ -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