github.com/status-im/status-go@v1.1.0/discovery/discv5.go (about) 1 package discovery 2 3 import ( 4 "crypto/ecdsa" 5 "net" 6 "sync" 7 "time" 8 9 "github.com/ethereum/go-ethereum/log" 10 "github.com/ethereum/go-ethereum/p2p/discv5" 11 ) 12 13 // NewDiscV5 creates instances of discovery v5 facade. 14 func NewDiscV5(prv *ecdsa.PrivateKey, laddr string, bootnodes []*discv5.Node) *DiscV5 { 15 return &DiscV5{ 16 prv: prv, 17 laddr: laddr, 18 bootnodes: bootnodes, 19 } 20 } 21 22 // DiscV5 is a facade for ethereum discv5 implementation. 23 type DiscV5 struct { 24 mu sync.Mutex 25 net *discv5.Network 26 27 prv *ecdsa.PrivateKey 28 laddr string 29 bootnodes []*discv5.Node 30 } 31 32 // Running returns true if v5 server is started. 33 func (d *DiscV5) Running() bool { 34 d.mu.Lock() 35 defer d.mu.Unlock() 36 return d.net != nil 37 } 38 39 // Start creates v5 server and stores pointer to it. 40 func (d *DiscV5) Start() error { 41 d.mu.Lock() 42 defer d.mu.Unlock() 43 log.Debug("Starting discovery", "listen address", d.laddr) 44 addr, err := net.ResolveUDPAddr("udp", d.laddr) 45 if err != nil { 46 return err 47 } 48 conn, err := net.ListenUDP("udp", addr) 49 if err != nil { 50 return err 51 } 52 ntab, err := discv5.ListenUDP(d.prv, conn, "", nil) 53 if err != nil { 54 return err 55 } 56 if err := ntab.SetFallbackNodes(d.bootnodes); err != nil { 57 return err 58 } 59 d.net = ntab 60 return nil 61 } 62 63 // Stop closes v5 server listener and removes pointer. 64 func (d *DiscV5) Stop() error { 65 d.mu.Lock() 66 defer d.mu.Unlock() 67 if d.net == nil { 68 return nil 69 } 70 d.net.Close() 71 d.net = nil 72 return nil 73 } 74 75 // Register creates a register request in v5 server. 76 // It will block until stop is closed. 77 func (d *DiscV5) Register(topic string, stop chan struct{}) error { 78 d.net.RegisterTopic(discv5.Topic(topic), stop) 79 return nil 80 } 81 82 // Discover creates search request in v5 server. Results will be published to found channel. 83 // It will block until period is closed. 84 func (d *DiscV5) Discover(topic string, period <-chan time.Duration, found chan<- *discv5.Node, lookup chan<- bool) error { 85 d.net.SearchTopic(discv5.Topic(topic), period, found, lookup) 86 return nil 87 }