@@ -2,41 +2,42 @@ package network
2
2
3
3
import (
4
4
"errors"
5
+ "fmt"
6
+ "slices"
7
+ "strings"
5
8
6
9
"github.com/NilFoundation/nil/nil/common"
7
10
"github.com/libp2p/go-libp2p/core/peer"
11
+ ma "github.com/multiformats/go-multiaddr"
12
+ "github.com/spf13/pflag"
8
13
"gopkg.in/yaml.v3"
9
14
)
10
15
11
16
type AddrInfo peer.AddrInfo
12
17
18
+ var _ pflag.Value = (* AddrInfo )(nil )
19
+
13
20
func (a AddrInfo ) Empty () bool {
14
21
return errors .Is (a .ID .Validate (), peer .ErrEmptyPeerID )
15
22
}
16
23
17
24
func (a * AddrInfo ) Set (value string ) error {
18
- addr , err := peer . AddrInfoFromString (value )
25
+ addrInfos , err := addrInfosFromString (value )
19
26
if err != nil {
20
27
return err
21
28
}
22
- * a = AddrInfo (* addr )
29
+ if len (addrInfos ) == 0 {
30
+ return fmt .Errorf ("%s is not a valid address" , value )
31
+ }
32
+ if len (addrInfos ) > 1 {
33
+ return fmt .Errorf ("not all multiaddresses belong to the same peer: %s" , value )
34
+ }
35
+ * a = AddrInfo (addrInfos [0 ])
23
36
return nil
24
37
}
25
38
26
39
func (a AddrInfo ) String () string {
27
- mu , err := peer .AddrInfoToP2pAddrs ((* peer .AddrInfo )(& a ))
28
- if err != nil {
29
- return err .Error ()
30
- }
31
- values := make ([]string , len (mu ))
32
- for i , val := range mu {
33
- values [i ] = val .String ()
34
- }
35
- str , err := common .WriteAsCSV (values )
36
- if err != nil {
37
- return err .Error ()
38
- }
39
- return str
40
+ return addrInfosToString (peer .AddrInfo (a ))
40
41
}
41
42
42
43
func (a * AddrInfo ) Type () string {
@@ -59,12 +60,136 @@ func (a *AddrInfo) UnmarshalYAML(value *yaml.Node) error {
59
60
return a .UnmarshalText ([]byte (value .Value ))
60
61
}
61
62
62
- type AddrInfoSlice = common.PValueSlice [* AddrInfo , AddrInfo ]
63
+ type AddrInfoSlice []peer.AddrInfo
64
+
65
+ func AsAddrInfoSlice (addrInfos ... AddrInfo ) AddrInfoSlice {
66
+ return slices .Collect (
67
+ common .Transform (
68
+ slices .Values (addrInfos ),
69
+ func (a AddrInfo ) peer.AddrInfo { return peer .AddrInfo (a ) }))
70
+ }
71
+
72
+ var _ pflag.Value = (* AddrInfoSlice )(nil )
73
+
74
+ func (s * AddrInfoSlice ) Set (value string ) (err error ) {
75
+ * s , err = addrInfosFromString (value )
76
+ return
77
+ }
78
+
79
+ // String returns one multiaddress per item including PeerID, comma-separated
80
+ func (s * AddrInfoSlice ) String () string {
81
+ return addrInfosToString (* s ... )
82
+ }
83
+
84
+ func (s * AddrInfoSlice ) Type () string {
85
+ return "[]AddrInfo"
86
+ }
87
+
88
+ // Strings returns one multiaddress per item including PeerID, in each array element
89
+ func (s * AddrInfoSlice ) Strings () ([]string , error ) {
90
+ return addrInfosToStrings (* s ... )
91
+ }
92
+
93
+ func (s * AddrInfoSlice ) FromStrings (addrs []string ) (err error ) {
94
+ * s , err = addrInfosFromStrings (addrs )
95
+ return
96
+ }
97
+
98
+ func (s AddrInfoSlice ) MarshalText () ([]byte , error ) {
99
+ return []byte (s .String ()), nil
100
+ }
101
+
102
+ func (s * AddrInfoSlice ) UnmarshalText (text []byte ) (err error ) {
103
+ return s .Set (string (text ))
104
+ }
105
+
106
+ func (s AddrInfoSlice ) MarshalYAML () (any , error ) {
107
+ return addrInfosToStrings (s ... )
108
+ }
109
+
110
+ func (s * AddrInfoSlice ) UnmarshalYAML (node * yaml.Node ) error {
111
+ if node .Kind != yaml .SequenceNode {
112
+ return fmt .Errorf ("expected sequence node for AddrInfoSlice, got %s" , kindToString (node .Kind ))
113
+ }
114
+
115
+ addrs := make ([]string , len (node .Content ))
116
+ for i , item := range node .Content {
117
+ if item .Kind != yaml .ScalarNode {
118
+ return fmt .Errorf ("expected scalar value at index %d, got %s" , i , kindToString (item .Kind ))
119
+ }
120
+ addrs [i ] = item .Value
121
+ }
122
+ return s .FromStrings (addrs )
123
+ }
124
+
125
+ func addrInfosFromStrings (addrs []string ) ([]peer.AddrInfo , error ) {
126
+ var err error
127
+ mas := make ([]ma.Multiaddr , len (addrs ))
128
+ for i , addr := range addrs {
129
+ mas [i ], err = ma .NewMultiaddr (addr )
130
+ if err != nil {
131
+ return nil , err
132
+ }
133
+ }
134
+
135
+ addrInfos , err := peer .AddrInfosFromP2pAddrs (mas ... )
136
+ if err != nil {
137
+ return nil , err
138
+ }
139
+ slices .SortFunc (addrInfos , func (l , r peer.AddrInfo ) int {
140
+ return strings .Compare (string (l .ID ), string (r .ID ))
141
+ })
142
+ return addrInfos , nil
143
+ }
144
+
145
+ func addrInfosFromString (value string ) ([]peer.AddrInfo , error ) {
146
+ addrs , err := common .ReadAsCSV (value )
147
+ if err != nil {
148
+ return nil , err
149
+ }
150
+ return addrInfosFromStrings (addrs )
151
+ }
152
+
153
+ func addrInfosToStrings (addrInfos ... peer.AddrInfo ) ([]string , error ) {
154
+ result := make ([]string , 0 , len (addrInfos ))
155
+ for _ , addrInfo := range addrInfos {
156
+ multiAddrs , err := peer .AddrInfoToP2pAddrs (& addrInfo )
157
+ if err != nil {
158
+ return nil , err
159
+ }
160
+ result = slices .AppendSeq (
161
+ result ,
162
+ common .Transform (
163
+ slices .Values (multiAddrs ),
164
+ func (addr ma.Multiaddr ) string { return addr .String () }))
165
+ }
166
+ return result , nil
167
+ }
168
+
169
+ func addrInfosToString (addrInfos ... peer.AddrInfo ) string {
170
+ addrs , err := addrInfosToStrings (addrInfos ... )
171
+ if err != nil {
172
+ return err .Error ()
173
+ }
174
+ result , err := common .WriteAsCSV (addrs )
175
+ if err != nil {
176
+ return err .Error ()
177
+ }
178
+ return result
179
+ }
63
180
64
- func ToLibP2pAddrInfoSlice (s AddrInfoSlice ) []peer.AddrInfo {
65
- res := make ([]peer.AddrInfo , len (s ))
66
- for i , a := range s {
67
- res [i ] = peer .AddrInfo (a )
181
+ func kindToString (kind yaml.Kind ) string {
182
+ switch kind {
183
+ case yaml .DocumentNode :
184
+ return "document node"
185
+ case yaml .SequenceNode :
186
+ return "sequence node"
187
+ case yaml .MappingNode :
188
+ return "mapping node"
189
+ case yaml .ScalarNode :
190
+ return "scalar node"
191
+ case yaml .AliasNode :
192
+ return "alias node"
68
193
}
69
- return res
194
+ return "unknown node type"
70
195
}
0 commit comments