diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go index 350b85df1e..0b872a42bf 100644 --- a/cmd/bootnode/main.go +++ b/cmd/bootnode/main.go @@ -22,48 +22,20 @@ import ( "flag" "fmt" "net" - "os" - "time" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/nat" - "github.com/ethereum/go-ethereum/p2p/netutil" ) func main() { var ( - listenAddr = flag.String("addr", ":30301", "listen address") - genKey = flag.String("genkey", "", "generate a node key") - writeAddr = flag.Bool("writeaddress", false, "write out the node's public key and quit") - nodeKeyFile = flag.String("nodekey", "", "private key filename") - nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") - natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|pmp:|extip:)") - netrestrict = flag.String("netrestrict", "", "restrict network communication to the given IP networks (CIDR masks)") - runv5 = flag.Bool("v5", false, "run a v5 topic discovery bootnode") - verbosity = flag.Int("verbosity", 3, "log verbosity (0-5)") - vmodule = flag.String("vmodule", "", "log verbosity pattern") - + genKey = flag.String("genkey", "", "generate a node key") nodeKey *ecdsa.PrivateKey err error ) flag.Parse() - - glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false)) - slogVerbosity := log.FromLegacyLevel(*verbosity) - glogger.Verbosity(slogVerbosity) - glogger.Vmodule(*vmodule) - log.SetDefault(log.NewLogger(glogger)) - - natm, err := nat.Parse(*natdesc) - if err != nil { - utils.Fatalf("-nat: %v", err) - } - switch { - case *genKey != "": + if *genKey != "" { nodeKey, err = crypto.GenerateKey() if err != nil { utils.Fatalf("could not generate key: %v", err) @@ -71,139 +43,7 @@ func main() { if err = crypto.SaveECDSA(*genKey, nodeKey); err != nil { utils.Fatalf("%v", err) } - if !*writeAddr { - return - } - case *nodeKeyFile == "" && *nodeKeyHex == "": - utils.Fatalf("Use -nodekey or -nodekeyhex to specify a private key") - case *nodeKeyFile != "" && *nodeKeyHex != "": - utils.Fatalf("Options -nodekey and -nodekeyhex are mutually exclusive") - case *nodeKeyFile != "": - if nodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { - utils.Fatalf("-nodekey: %v", err) - } - case *nodeKeyHex != "": - if nodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { - utils.Fatalf("-nodekeyhex: %v", err) - } + n := enode.NewV4(&nodeKey.PublicKey, net.IP{127, 0, 0, 1}, 0, 30303) + fmt.Println(n.URLv4()) } - - if *writeAddr { - fmt.Printf("%x\n", crypto.FromECDSAPub(&nodeKey.PublicKey)[1:]) - os.Exit(0) - } - - var restrictList *netutil.Netlist - if *netrestrict != "" { - restrictList, err = netutil.ParseNetlist(*netrestrict) - if err != nil { - utils.Fatalf("-netrestrict: %v", err) - } - } - - addr, err := net.ResolveUDPAddr("udp", *listenAddr) - if err != nil { - utils.Fatalf("-ResolveUDPAddr: %v", err) - } - conn, err := net.ListenUDP("udp", addr) - if err != nil { - utils.Fatalf("-ListenUDP: %v", err) - } - defer conn.Close() - - db, _ := enode.OpenDB("") - ln := enode.NewLocalNode(db, nodeKey) - - listenerAddr := conn.LocalAddr().(*net.UDPAddr) - if natm != nil && !listenerAddr.IP.IsLoopback() { - natAddr := doPortMapping(natm, ln, listenerAddr) - if natAddr != nil { - listenerAddr = natAddr - } - } - - printNotice(&nodeKey.PublicKey, *listenerAddr) - cfg := discover.Config{ - PrivateKey: nodeKey, - NetRestrict: restrictList, - } - if *runv5 { - if _, err := discover.ListenV5(conn, ln, cfg); err != nil { - utils.Fatalf("%v", err) - } - } else { - if _, err := discover.ListenUDP(conn, ln, cfg); err != nil { - utils.Fatalf("%v", err) - } - } - - select {} -} - -func printNotice(nodeKey *ecdsa.PublicKey, addr net.UDPAddr) { - if addr.IP.IsUnspecified() { - addr.IP = net.IP{127, 0, 0, 1} - } - n := enode.NewV4(nodeKey, addr.IP, 0, addr.Port) - fmt.Println(n.URLv4()) - fmt.Println("Note: you're using cmd/bootnode, a developer tool.") - fmt.Println("We recommend using a regular node as bootstrap node for production deployments.") -} - -func doPortMapping(natm nat.Interface, ln *enode.LocalNode, addr *net.UDPAddr) *net.UDPAddr { - const ( - protocol = "udp" - name = "ethereum discovery" - ) - newLogger := func(external int, internal int) log.Logger { - return log.New("proto", protocol, "extport", external, "intport", internal, "interface", natm) - } - - var ( - intport = addr.Port - extaddr = &net.UDPAddr{IP: addr.IP, Port: addr.Port} - mapTimeout = nat.DefaultMapTimeout - log = newLogger(addr.Port, intport) - ) - addMapping := func() { - // Get the external address. - var err error - extaddr.IP, err = natm.ExternalIP() - if err != nil { - log.Debug("Couldn't get external IP", "err", err) - return - } - // Create the mapping. - p, err := natm.AddMapping(protocol, extaddr.Port, intport, name, mapTimeout) - if err != nil { - log.Debug("Couldn't add port mapping", "err", err) - return - } - if p != uint16(extaddr.Port) { - extaddr.Port = int(p) - log = newLogger(extaddr.Port, intport) - log.Info("NAT mapped alternative port") - } else { - log.Info("NAT mapped port") - } - // Update IP/port information of the local node. - ln.SetStaticIP(extaddr.IP) - ln.SetFallbackUDP(extaddr.Port) - } - - // Perform mapping once, synchronously. - log.Info("Attempting port mapping") - addMapping() - - // Refresh the mapping periodically. - go func() { - refresh := time.NewTimer(mapTimeout) - defer refresh.Stop() - for range refresh.C { - addMapping() - refresh.Reset(mapTimeout) - } - }() - - return extaddr }