github.com/MetalBlockchain/metalgo@v1.11.9/tests/fixture/tmpnet/utils.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package tmpnet 5 6 import ( 7 "context" 8 "encoding/json" 9 "errors" 10 "fmt" 11 "time" 12 13 "github.com/MetalBlockchain/metalgo/ids" 14 "github.com/MetalBlockchain/metalgo/utils/crypto/secp256k1" 15 ) 16 17 const ( 18 DefaultNodeTickerInterval = 50 * time.Millisecond 19 ) 20 21 var ErrNotRunning = errors.New("not running") 22 23 // WaitForHealthy blocks until Node.IsHealthy returns true or an error (including context timeout) is observed. 24 func WaitForHealthy(ctx context.Context, node *Node) error { 25 if _, ok := ctx.Deadline(); !ok { 26 return fmt.Errorf("unable to wait for health for node %q with a context without a deadline", node.NodeID) 27 } 28 ticker := time.NewTicker(DefaultNodeTickerInterval) 29 defer ticker.Stop() 30 31 for { 32 healthy, err := node.IsHealthy(ctx) 33 if err != nil && !errors.Is(err, ErrNotRunning) { 34 return fmt.Errorf("failed to wait for health of node %q: %w", node.NodeID, err) 35 } 36 if healthy { 37 return nil 38 } 39 40 select { 41 case <-ctx.Done(): 42 return fmt.Errorf("failed to wait for health of node %q before timeout: %w", node.NodeID, ctx.Err()) 43 case <-ticker.C: 44 } 45 } 46 } 47 48 // NodeURI associates a node ID with its API URI. 49 type NodeURI struct { 50 NodeID ids.NodeID 51 URI string 52 } 53 54 func GetNodeURIs(nodes []*Node) []NodeURI { 55 uris := make([]NodeURI, 0, len(nodes)) 56 for _, node := range nodes { 57 if node.IsEphemeral { 58 // Avoid returning URIs for nodes whose lifespan is indeterminate 59 continue 60 } 61 // Only append URIs that are not empty. A node may have an 62 // empty URI if it is not currently running. 63 if len(node.URI) > 0 { 64 uris = append(uris, NodeURI{ 65 NodeID: node.NodeID, 66 URI: node.URI, 67 }) 68 } 69 } 70 return uris 71 } 72 73 // Marshal to json with default prefix and indent. 74 func DefaultJSONMarshal(v interface{}) ([]byte, error) { 75 return json.MarshalIndent(v, "", " ") 76 } 77 78 // Helper simplifying creation of a set of private keys 79 func NewPrivateKeys(keyCount int) ([]*secp256k1.PrivateKey, error) { 80 keys := make([]*secp256k1.PrivateKey, 0, keyCount) 81 for i := 0; i < keyCount; i++ { 82 key, err := secp256k1.NewPrivateKey() 83 if err != nil { 84 return nil, fmt.Errorf("failed to generate private key: %w", err) 85 } 86 keys = append(keys, key) 87 } 88 return keys, nil 89 } 90 91 func NodesToIDs(nodes ...*Node) []ids.NodeID { 92 nodeIDs := make([]ids.NodeID, len(nodes)) 93 for i, node := range nodes { 94 nodeIDs[i] = node.NodeID 95 } 96 return nodeIDs 97 }