status-go/discovery/discv5.go

90 lines
2.0 KiB
Go
Raw Normal View History

package discovery
2018-04-12 13:08:49 +00:00
import (
2018-07-03 11:27:04 +00:00
"crypto/ecdsa"
2018-04-12 13:08:49 +00:00
"net"
2018-07-03 11:27:04 +00:00
"sync"
"time"
2018-04-12 13:08:49 +00:00
"go.uber.org/zap"
2018-04-12 13:08:49 +00:00
"github.com/ethereum/go-ethereum/p2p/discv5"
"github.com/status-im/status-go/logutils"
2018-04-12 13:08:49 +00:00
)
2018-07-03 11:27:04 +00:00
// NewDiscV5 creates instances of discovery v5 facade.
func NewDiscV5(prv *ecdsa.PrivateKey, laddr string, bootnodes []*discv5.Node) *DiscV5 {
return &DiscV5{
prv: prv,
laddr: laddr,
bootnodes: bootnodes,
}
}
// DiscV5 is a facade for ethereum discv5 implementation.
type DiscV5 struct {
mu sync.Mutex
net *discv5.Network
prv *ecdsa.PrivateKey
laddr string
bootnodes []*discv5.Node
}
// Running returns true if v5 server is started.
func (d *DiscV5) Running() bool {
d.mu.Lock()
defer d.mu.Unlock()
return d.net != nil
}
// Start creates v5 server and stores pointer to it.
func (d *DiscV5) Start() error {
d.mu.Lock()
defer d.mu.Unlock()
logutils.ZapLogger().Debug("Starting discovery", zap.String("listen address", d.laddr))
2018-07-03 11:27:04 +00:00
addr, err := net.ResolveUDPAddr("udp", d.laddr)
2018-04-12 13:08:49 +00:00
if err != nil {
2018-07-03 11:27:04 +00:00
return err
2018-04-12 13:08:49 +00:00
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
2018-07-03 11:27:04 +00:00
return err
2018-04-12 13:08:49 +00:00
}
2018-12-19 10:02:07 +00:00
ntab, err := discv5.ListenUDP(d.prv, conn, "", nil)
2018-04-12 13:08:49 +00:00
if err != nil {
2018-07-03 11:27:04 +00:00
return err
}
if err := ntab.SetFallbackNodes(d.bootnodes); err != nil {
return err
2018-04-12 13:08:49 +00:00
}
2018-07-03 11:27:04 +00:00
d.net = ntab
return nil
}
// Stop closes v5 server listener and removes pointer.
func (d *DiscV5) Stop() error {
d.mu.Lock()
defer d.mu.Unlock()
if d.net == nil {
return nil
2018-04-12 13:08:49 +00:00
}
2018-07-03 11:27:04 +00:00
d.net.Close()
d.net = nil
return nil
}
// Register creates a register request in v5 server.
// It will block until stop is closed.
func (d *DiscV5) Register(topic string, stop chan struct{}) error {
d.net.RegisterTopic(discv5.Topic(topic), stop)
return nil
}
// Discover creates search request in v5 server. Results will be published to found channel.
// It will block until period is closed.
func (d *DiscV5) Discover(topic string, period <-chan time.Duration, found chan<- *discv5.Node, lookup chan<- bool) error {
d.net.SearchTopic(discv5.Topic(topic), period, found, lookup)
return nil
2018-04-12 13:08:49 +00:00
}