github.com/status-im/status-go@v1.1.0/cmd/bootnode/main.go (about) 1 // bootnode runs a bootstrap node for the Ethereum Discovery Protocol. 2 package main 3 4 import ( 5 "crypto/ecdsa" 6 "encoding/hex" 7 "flag" 8 "fmt" 9 "net" 10 "os" 11 12 "github.com/ethereum/go-ethereum/crypto" 13 "github.com/ethereum/go-ethereum/log" 14 "github.com/ethereum/go-ethereum/p2p/discv5" 15 ) 16 17 var ( 18 writeAddr = flag.Bool("writeaddress", false, "write out the node's public key and quit") 19 listenAddr = flag.String("addr", ":30301", "listen address") 20 genKeyFile = flag.String("genkey", "", "generate a node key") 21 nodeKeyFile = flag.String("nodekey", "", "private key filename") 22 keydata = flag.String("keydata", "", "hex encoded private key") 23 verbosity = flag.Int("verbosity", int(log.LvlInfo), "log verbosity (0-9)") 24 vmodule = flag.String("vmodule", "", "log verbosity pattern") 25 nursery = bootnodes{} 26 nodeKey *ecdsa.PrivateKey 27 err error 28 ) 29 30 type bootnodes []*discv5.Node 31 32 func (f *bootnodes) String() string { 33 return "discv5 nodes" 34 } 35 36 // Set unmarshals enode into discv5.Node. 37 func (f *bootnodes) Set(value string) error { 38 n, err := discv5.ParseNode(value) 39 if err != nil { 40 return err 41 } 42 *f = append(*f, n) 43 return nil 44 } 45 46 func main() { 47 flag.Var(&nursery, "n", "These nodes are used to connect to the network if the table is empty and there are no known nodes in the database.") 48 flag.Parse() 49 50 glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) 51 glogger.Verbosity(log.Lvl(*verbosity)) 52 if err = glogger.Vmodule(*vmodule); err != nil { 53 log.Crit("Failed to set glog verbosity", "value", *vmodule, "err", err) 54 } 55 log.Root().SetHandler(glogger) 56 57 if len(*genKeyFile) != 0 { 58 log.Info("Generating key file", "path", *genKeyFile) 59 key, err := crypto.GenerateKey() 60 if err != nil { 61 log.Crit("unable to generate key", "error", err) 62 } 63 if err := crypto.SaveECDSA(*genKeyFile, key); err != nil { 64 log.Crit("unable to save key", "error", err) 65 } 66 os.Exit(0) 67 } 68 if len(*nodeKeyFile) == 0 && len(*keydata) == 0 { 69 log.Crit("either `nodekey` or `keydata` must be provided") 70 } 71 if len(*nodeKeyFile) != 0 { 72 nodeKey, err = crypto.LoadECDSA(*nodeKeyFile) 73 if err != nil { 74 log.Crit("Failed to load ecdsa key from", "file", *nodeKeyFile, "error", err) 75 } 76 } else if len(*keydata) != 0 { 77 log.Warn("key will be visible in process list. should be used only for tests") 78 key, err := hex.DecodeString(*keydata) 79 if err != nil { 80 log.Crit("unable to decode hex", "data", keydata, "error", err) 81 } 82 nodeKey, err = crypto.ToECDSA(key) 83 if err != nil { 84 log.Crit("unable to convert decoded hex into ecdsa.PrivateKey", "data", key, "error", err) 85 } 86 } 87 if *writeAddr { 88 // we remove the first uncompressed byte since it's not used in an enode address 89 fmt.Printf("%x\n", crypto.FromECDSAPub(&nodeKey.PublicKey)[1:]) 90 os.Exit(0) 91 } 92 93 addr, err := net.ResolveUDPAddr("udp", *listenAddr) 94 if err != nil { 95 log.Crit("Unable to resolve UDP", "address", *listenAddr, "error", err) 96 } 97 conn, err := net.ListenUDP("udp", addr) 98 if err != nil { 99 log.Crit("Unable to listen on udp", "address", addr, "error", err) 100 } 101 102 tab, err := discv5.ListenUDP(nodeKey, conn, "", nil) 103 if err != nil { 104 log.Crit("Failed to create discovery v5 table:", "error", err) 105 } 106 defer tab.Close() 107 if err := tab.SetFallbackNodes(nursery); err != nil { 108 log.Crit("Failed to set fallback", "nodes", nursery, "error", err) 109 } 110 111 select {} 112 }