-
Notifications
You must be signed in to change notification settings - Fork 170
/
utils.go
180 lines (154 loc) · 4.33 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package common
import (
"encoding/json"
"fmt"
"net"
"os"
"path/filepath"
"strconv"
"github.com/multiformats/go-multiaddr"
"github.com/rs/zerolog"
"github.com/onflow/crypto"
"github.com/onflow/flow-go/model/bootstrap"
"github.com/onflow/flow-go/model/encodable"
"github.com/onflow/flow-go/model/flow"
"github.com/onflow/flow-go/network/p2p/utils"
"github.com/onflow/flow-go/utils/io"
)
func FilesInDir(dir string) ([]string, error) {
exists, err := PathExists(dir)
if err != nil {
return nil, fmt.Errorf("could not check if dir exists: %w", err)
}
if !exists {
return nil, fmt.Errorf("dir %v does not exist", dir)
}
var files []string
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
files = append(files, path)
}
return nil
})
return files, err
}
// PathExists
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
func ReadJSON(path string, target interface{}) error {
dat, err := io.ReadFile(path)
if err != nil {
return fmt.Errorf("cannot read json: %w", err)
}
err = json.Unmarshal(dat, target)
if err != nil {
return fmt.Errorf("cannot unmarshal json in file %s: %w", path, err)
}
return nil
}
func WriteJSON(path string, out string, data interface{}) error {
bz, err := json.MarshalIndent(data, "", " ")
if err != nil {
return fmt.Errorf("cannot marshal json: %w", err)
}
return WriteText(path, out, bz)
}
func WriteText(path string, out string, data []byte) error {
path = filepath.Join(out, path)
err := os.MkdirAll(filepath.Dir(path), 0755)
if err != nil {
return fmt.Errorf("could not create output dir: %w", err)
}
err = os.WriteFile(path, data, 0644)
if err != nil {
return fmt.Errorf("could not write file: %w", err)
}
return nil
}
func PubKeyToString(key crypto.PublicKey) string {
return fmt.Sprintf("%x", key.Encode())
}
func NodeCountByRole(nodes []bootstrap.NodeInfo) map[flow.Role]uint16 {
roleCounts := map[flow.Role]uint16{
flow.RoleCollection: 0,
flow.RoleConsensus: 0,
flow.RoleExecution: 0,
flow.RoleVerification: 0,
flow.RoleAccess: 0,
}
for _, node := range nodes {
roleCounts[node.Role] = roleCounts[node.Role] + 1
}
return roleCounts
}
// ValidateAddressFormat validates the address provided by pretty much doing what the network layer would do before
// starting the node
func ValidateAddressFormat(log zerolog.Logger, address string) {
checkErr := func(err error) {
if err != nil {
log.Fatal().Err(err).Str("address", address).Msg("invalid address format.\n" +
`Address needs to be in the format hostname:port or ip:port e.g. "flow.com:3569"`)
}
}
// split address into ip/hostname and port
ip, port, err := net.SplitHostPort(address)
checkErr(err)
// check that port number is indeed a number
_, err = strconv.Atoi(port)
checkErr(err)
// create a libp2p address from the ip and port
lp2pAddr := utils.MultiAddressStr(ip, port)
_, err = multiaddr.NewMultiaddr(lp2pAddr)
checkErr(err)
}
// ValidateNodeID returns an error if node ID is non-zero.
// Args:
// - nodeID: the node ID to validate.
// Returns:
// - error: if node id is the zero value.
func ValidateNodeID(nodeID flow.Identifier) error {
if nodeID == flow.ZeroID {
return fmt.Errorf("NodeID must not be zero")
}
return nil
}
// ValidateNetworkPubKey returns an error if network public key is nil.
// Args:
// - key: the public key.
// Returns:
// - error: if the network key is nil.
func ValidateNetworkPubKey(key encodable.NetworkPubKey) error {
if key.PublicKey == nil {
return fmt.Errorf("network public key must not be nil")
}
return nil
}
// ValidateStakingPubKey returns an error if the staking key is nil.
// Args:
// - key: the public key.
// Returns:
// - error: if the staking key is nil.
func ValidateStakingPubKey(key encodable.StakingPubKey) error {
if key.PublicKey == nil {
return fmt.Errorf("staking public key must not be nil")
}
return nil
}
// ValidateWeight returns true if weight is greater than 0.
// Args:
// - weight: the weight to check.
// Returns:
// - bool: true if weight is greater than 0.
func ValidateWeight(weight uint64) bool {
return weight > 0
}
// PartnerWeights is the format of the JSON file specifying partner node weights.
type PartnerWeights map[flow.Identifier]uint64