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  }