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 }