github.com/MetalBlockchain/metalgo@v1.11.9/chains/subnets.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package chains
     5  
     6  import (
     7  	"errors"
     8  	"sync"
     9  
    10  	"github.com/MetalBlockchain/metalgo/ids"
    11  	"github.com/MetalBlockchain/metalgo/subnets"
    12  	"github.com/MetalBlockchain/metalgo/utils/constants"
    13  )
    14  
    15  var ErrNoPrimaryNetworkConfig = errors.New("no subnet config for primary network found")
    16  
    17  // Subnets holds the currently running subnets on this node
    18  type Subnets struct {
    19  	nodeID  ids.NodeID
    20  	configs map[ids.ID]subnets.Config
    21  
    22  	lock    sync.RWMutex
    23  	subnets map[ids.ID]subnets.Subnet
    24  }
    25  
    26  // GetOrCreate returns a subnet running on this node, or creates one if it was
    27  // not running before. Returns the subnet and if the subnet was created.
    28  func (s *Subnets) GetOrCreate(subnetID ids.ID) (subnets.Subnet, bool) {
    29  	s.lock.Lock()
    30  	defer s.lock.Unlock()
    31  
    32  	if subnet, ok := s.subnets[subnetID]; ok {
    33  		return subnet, false
    34  	}
    35  
    36  	// Default to the primary network config if a subnet config was not
    37  	// specified
    38  	config, ok := s.configs[subnetID]
    39  	if !ok {
    40  		config = s.configs[constants.PrimaryNetworkID]
    41  	}
    42  
    43  	subnet := subnets.New(s.nodeID, config)
    44  	s.subnets[subnetID] = subnet
    45  
    46  	return subnet, true
    47  }
    48  
    49  // Bootstrapping returns the subnetIDs of any chains that are still
    50  // bootstrapping.
    51  func (s *Subnets) Bootstrapping() []ids.ID {
    52  	s.lock.RLock()
    53  	defer s.lock.RUnlock()
    54  
    55  	subnetsBootstrapping := make([]ids.ID, 0, len(s.subnets))
    56  	for subnetID, subnet := range s.subnets {
    57  		if !subnet.IsBootstrapped() {
    58  			subnetsBootstrapping = append(subnetsBootstrapping, subnetID)
    59  		}
    60  	}
    61  
    62  	return subnetsBootstrapping
    63  }
    64  
    65  // NewSubnets returns an instance of Subnets
    66  func NewSubnets(
    67  	nodeID ids.NodeID,
    68  	configs map[ids.ID]subnets.Config,
    69  ) (*Subnets, error) {
    70  	if _, ok := configs[constants.PrimaryNetworkID]; !ok {
    71  		return nil, ErrNoPrimaryNetworkConfig
    72  	}
    73  
    74  	s := &Subnets{
    75  		nodeID:  nodeID,
    76  		configs: configs,
    77  		subnets: make(map[ids.ID]subnets.Subnet),
    78  	}
    79  
    80  	_, _ = s.GetOrCreate(constants.PrimaryNetworkID)
    81  	return s, nil
    82  }