@@ -154,14 +154,24 @@ func (ln *localNetwork) RegisterBlockchainAliases(
154
154
return nil
155
155
}
156
156
157
+ func (ln * localNetwork ) AddSubnetValidators (
158
+ ctx context.Context ,
159
+ subnetSpecs []network.SubnetValidatorsSpec ,
160
+ ) error {
161
+ ln .lock .Lock ()
162
+ defer ln .lock .Unlock ()
163
+
164
+ return ln .addSubnetValidators (ctx , subnetSpecs )
165
+ }
166
+
157
167
func (ln * localNetwork ) RemoveSubnetValidators (
158
168
ctx context.Context ,
159
- removeSubnetSpecs []network.RemoveSubnetValidatorSpec ,
169
+ subnetSpecs []network.SubnetValidatorsSpec ,
160
170
) error {
161
171
ln .lock .Lock ()
162
172
defer ln .lock .Unlock ()
163
173
164
- return ln .removeSubnetValidators (ctx , removeSubnetSpecs )
174
+ return ln .removeSubnetValidators (ctx , subnetSpecs )
165
175
}
166
176
167
177
func (ln * localNetwork ) AddPermissionlessValidators (
@@ -342,7 +352,7 @@ func (ln *localNetwork) installCustomChains(
342
352
return nil , err
343
353
}
344
354
345
- if err = ln .addSubnetValidators (ctx , platformCli , w , subnetIDs , subnetSpecs ); err != nil {
355
+ if err = ln .issueSubnetValidatorTxs (ctx , platformCli , w , subnetIDs , subnetSpecs ); err != nil {
346
356
return nil , err
347
357
}
348
358
@@ -409,6 +419,88 @@ func (ln *localNetwork) installCustomChains(
409
419
return chainInfos , nil
410
420
}
411
421
422
+ func (ln * localNetwork ) addSubnetValidators (
423
+ ctx context.Context ,
424
+ subnetValidatorsSpecs []network.SubnetValidatorsSpec ,
425
+ ) error {
426
+ ln .log .Info (logging .Blue .Wrap (logging .Bold .Wrap ("add subnet validators" )))
427
+
428
+ clientURI , err := ln .getClientURI ()
429
+ if err != nil {
430
+ return err
431
+ }
432
+ platformCli := platformvm .NewClient (clientURI )
433
+
434
+ // wallet needs txs for all previously created subnets
435
+ subnetIDs := make ([]ids.ID , len (subnetValidatorsSpecs ))
436
+ for i , spec := range subnetValidatorsSpecs {
437
+ subnetID , err := ids .FromString (spec .SubnetID )
438
+ if err != nil {
439
+ return err
440
+ }
441
+ subnetIDs [i ] = subnetID
442
+ }
443
+ w , err := newWallet (ctx , clientURI , subnetIDs )
444
+ if err != nil {
445
+ return err
446
+ }
447
+
448
+ for _ , spec := range subnetValidatorsSpecs {
449
+ if len (spec .NodeNames ) == 0 {
450
+ return fmt .Errorf ("no validators provided for subnet %s" , spec .SubnetID )
451
+ }
452
+ }
453
+
454
+ // create new nodes
455
+ for _ , spec := range subnetValidatorsSpecs {
456
+ for _ , nodeName := range spec .NodeNames {
457
+ _ , ok := ln .nodes [nodeName ]
458
+ if ! ok {
459
+ ln .log .Info (logging .Green .Wrap (fmt .Sprintf ("adding new participant %s" , nodeName )))
460
+ if _ , err := ln .addNode (node.Config {
461
+ Name : nodeName ,
462
+ RedirectStdout : ln .redirectStdout ,
463
+ RedirectStderr : ln .redirectStderr ,
464
+ }); err != nil {
465
+ return err
466
+ }
467
+ }
468
+ }
469
+ }
470
+ if err := ln .healthy (ctx ); err != nil {
471
+ return err
472
+ }
473
+
474
+ // just ensure all nodes are primary validators (so can be subnet validators)
475
+ if err := ln .addPrimaryValidators (ctx , platformCli , w ); err != nil {
476
+ return err
477
+ }
478
+
479
+ // wait for nodes to be primary validators before trying to add them as subnet ones
480
+ if err = ln .waitPrimaryValidators (ctx , platformCli ); err != nil {
481
+ return err
482
+ }
483
+
484
+ subnetSpecs := []network.SubnetSpec {}
485
+ for _ , spec := range subnetValidatorsSpecs {
486
+ subnetSpecs = append (subnetSpecs , network.SubnetSpec {Participants : spec .NodeNames })
487
+ }
488
+
489
+ if err = ln .issueSubnetValidatorTxs (ctx , platformCli , w , subnetIDs , subnetSpecs ); err != nil {
490
+ return err
491
+ }
492
+
493
+ if err := ln .restartNodes (ctx , subnetIDs , subnetSpecs , nil , nil , nil ); err != nil {
494
+ return err
495
+ }
496
+
497
+ if err = ln .waitSubnetValidators (ctx , platformCli , subnetIDs , subnetSpecs ); err != nil {
498
+ return err
499
+ }
500
+
501
+ return nil
502
+ }
503
+
412
504
func (ln * localNetwork ) installSubnets (
413
505
ctx context.Context ,
414
506
subnetSpecs []network.SubnetSpec ,
@@ -479,7 +571,7 @@ func (ln *localNetwork) installSubnets(
479
571
return nil , err
480
572
}
481
573
482
- if err = ln .addSubnetValidators (ctx , platformCli , w , subnetIDs , subnetSpecs ); err != nil {
574
+ if err = ln .issueSubnetValidatorTxs (ctx , platformCli , w , subnetIDs , subnetSpecs ); err != nil {
483
575
return nil , err
484
576
}
485
577
@@ -586,7 +678,7 @@ func (ln *localNetwork) restartNodes(
586
678
subnetIDs []ids.ID ,
587
679
subnetSpecs []network.SubnetSpec ,
588
680
validatorSpecs []network.PermissionlessStakerSpec ,
589
- removeValidatorSpecs []network.RemoveSubnetValidatorSpec ,
681
+ removeValidatorSpecs []network.SubnetValidatorsSpec ,
590
682
nodesToRestartForBlockchainConfigUpdate set.Set [string ],
591
683
) (err error ) {
592
684
if (subnetSpecs != nil && validatorSpecs != nil ) || (subnetSpecs != nil && removeValidatorSpecs != nil ) ||
@@ -879,7 +971,7 @@ func importPChainFromXChain(ctx context.Context, w *wallet, owner *secp256k1fx.O
879
971
880
972
func (ln * localNetwork ) removeSubnetValidators (
881
973
ctx context.Context ,
882
- removeSubnetSpecs []network.RemoveSubnetValidatorSpec ,
974
+ removeSubnetSpecs []network.SubnetValidatorsSpec ,
883
975
) error {
884
976
ln .log .Info ("removing subnet validator tx" )
885
977
removeSubnetSpecIDs := make ([]ids.ID , len (removeSubnetSpecs ))
@@ -1314,7 +1406,7 @@ func createSubnets(
1314
1406
// add the nodes in subnet participant as validators of the given subnets, in case they are not
1315
1407
// the validation starts as soon as possible and its duration is as long as possible, that is,
1316
1408
// it ends at the time the primary network validation ends for the node
1317
- func (ln * localNetwork ) addSubnetValidators (
1409
+ func (ln * localNetwork ) issueSubnetValidatorTxs (
1318
1410
ctx context.Context ,
1319
1411
platformCli platformvm.Client ,
1320
1412
w * wallet ,
0 commit comments