|
84 | 84 | Name: "bootnodes", |
85 | 85 | Usage: "Comma separated nodes used for bootstrapping", |
86 | 86 | } |
| 87 | + nodekeyFlag = cli.StringFlag{ |
| 88 | + Name: "nodekey", |
| 89 | + Usage: "Hex-encoded node key", |
| 90 | + } |
| 91 | + nodedbFlag = cli.StringFlag{ |
| 92 | + Name: "nodedb", |
| 93 | + Usage: "Nodes database location", |
| 94 | + } |
| 95 | + listenAddrFlag = cli.StringFlag{ |
| 96 | + Name: "addr", |
| 97 | + Usage: "Listening address", |
| 98 | + } |
87 | 99 | crawlTimeoutFlag = cli.DurationFlag{ |
88 | 100 | Name: "timeout", |
89 | 101 | Usage: "Time limit for the crawl.", |
@@ -181,56 +193,75 @@ func discv4Crawl(ctx *cli.Context) error { |
181 | 193 | return nil |
182 | 194 | } |
183 | 195 |
|
184 | | -func parseBootnodes(ctx *cli.Context) ([]*enode.Node, error) { |
185 | | - s := utils.GetBootstrapNodes(ctx) |
186 | | - if ctx.IsSet(bootnodesFlag.Name) { |
187 | | - s = strings.Split(ctx.String(bootnodesFlag.Name), ",") |
188 | | - } |
189 | | - nodes := make([]*enode.Node, len(s)) |
190 | | - var err error |
191 | | - for i, record := range s { |
192 | | - nodes[i], err = parseNode(record) |
193 | | - if err != nil { |
194 | | - return nil, fmt.Errorf("invalid bootstrap node: %v", err) |
195 | | - } |
196 | | - } |
197 | | - return nodes, nil |
198 | | -} |
199 | | - |
200 | 196 | // startV4 starts an ephemeral discovery V4 node. |
201 | 197 | func startV4(ctx *cli.Context) *discover.UDPv4 { |
202 | 198 | networkId := ctx.GlobalUint64(networkIdFlag.Name) |
203 | | - socket, ln, cfg, err := listen(networkId) |
| 199 | + ln, config := makeDiscoveryConfig(ctx, networkId) |
| 200 | + socket := listen(ln, ctx.String(listenAddrFlag.Name)) |
| 201 | + disc, err := discover.ListenV4(socket, ln, config) |
204 | 202 | if err != nil { |
205 | 203 | exit(err) |
206 | 204 | } |
| 205 | + return disc |
| 206 | +} |
| 207 | + |
| 208 | +func makeDiscoveryConfig(ctx *cli.Context, networkId uint64) (*enode.LocalNode, discover.Config) { |
| 209 | + var cfg discover.Config |
| 210 | + |
| 211 | + if ctx.IsSet(nodekeyFlag.Name) { |
| 212 | + key, err := crypto.HexToECDSA(ctx.String(nodekeyFlag.Name)) |
| 213 | + if err != nil { |
| 214 | + exit(fmt.Errorf("-%s: %v", nodekeyFlag.Name, err)) |
| 215 | + } |
| 216 | + cfg.PrivateKey = key |
| 217 | + } else { |
| 218 | + cfg.PrivateKey, _ = crypto.GenerateKey() |
| 219 | + } |
| 220 | + |
207 | 221 | if commandHasFlag(ctx, bootnodesFlag) { |
208 | 222 | bn, err := parseBootnodes(ctx) |
209 | 223 | if err != nil { |
210 | 224 | exit(err) |
211 | 225 | } |
212 | 226 | cfg.Bootnodes = bn |
213 | 227 | } |
214 | | - disc, err := discover.ListenV4(socket, ln, cfg) |
| 228 | + |
| 229 | + dbpath := ctx.String(nodedbFlag.Name) |
| 230 | + db, err := enode.OpenDB(dbpath) |
215 | 231 | if err != nil { |
216 | 232 | exit(err) |
217 | 233 | } |
218 | | - return disc |
219 | | -} |
220 | | - |
221 | | -func listen(networkId uint64) (*net.UDPConn, *enode.LocalNode, discover.Config, error) { |
222 | | - var cfg discover.Config |
223 | | - cfg.PrivateKey, _ = crypto.GenerateKey() |
224 | | - db, _ := enode.OpenDB("") |
225 | 234 | ln := enode.NewLocalNode(db, cfg.PrivateKey, networkId) |
| 235 | + return ln, cfg |
| 236 | +} |
226 | 237 |
|
227 | | - socket, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IP{0, 0, 0, 0}}) |
| 238 | +func listen(ln *enode.LocalNode, addr string) *net.UDPConn { |
| 239 | + if addr == "" { |
| 240 | + addr = "0.0.0.0:0" |
| 241 | + } |
| 242 | + socket, err := net.ListenPacket("udp4", addr) |
228 | 243 | if err != nil { |
229 | | - db.Close() |
230 | | - return nil, nil, cfg, err |
| 244 | + exit(err) |
231 | 245 | } |
232 | | - addr := socket.LocalAddr().(*net.UDPAddr) |
| 246 | + usocket := socket.(*net.UDPConn) |
| 247 | + uaddr := socket.LocalAddr().(*net.UDPAddr) |
233 | 248 | ln.SetFallbackIP(net.IP{127, 0, 0, 1}) |
234 | | - ln.SetFallbackUDP(addr.Port) |
235 | | - return socket, ln, cfg, nil |
| 249 | + ln.SetFallbackUDP(uaddr.Port) |
| 250 | + return usocket |
| 251 | +} |
| 252 | + |
| 253 | +func parseBootnodes(ctx *cli.Context) ([]*enode.Node, error) { |
| 254 | + s := utils.GetBootstrapNodes(ctx) |
| 255 | + if ctx.IsSet(bootnodesFlag.Name) { |
| 256 | + s = strings.Split(ctx.String(bootnodesFlag.Name), ",") |
| 257 | + } |
| 258 | + nodes := make([]*enode.Node, len(s)) |
| 259 | + var err error |
| 260 | + for i, record := range s { |
| 261 | + nodes[i], err = parseNode(record) |
| 262 | + if err != nil { |
| 263 | + return nil, fmt.Errorf("invalid bootstrap node: %v", err) |
| 264 | + } |
| 265 | + } |
| 266 | + return nodes, nil |
236 | 267 | } |
0 commit comments