prysm-pulse/beacon-chain/p2p/discovery.go
Nishant Das 3cb32c3792
Implement Discv5 in Prysm (#3211)
* add discovery

* gaz

* add build options

* add udpPort

* add more changes

* refactor private key

* added discovery loop

* add ttl

* add ttl

* use ip type instead of string

* tests pass

* gaz and new test file

* add test

* add more tests

* add one more test

* adding multiAddr tests

* adding new protocol , listener

* fix keys

* more fixes

* more changes dialing peers works now

* gaz

* add more changes

* add more changes

* gaz

* add new test helpers

* new test

* fixed all tests

* gaz

* reduce sleep

* lint

* new changes

* change formats

* fix all this stuff

* remove discv5 protocol

* remove protocol

* remove port condition,too restrictive

* preston's feedback

* preston's feedback

* close all peers

* gaz

* remove unused func

* Update beacon-chain/p2p/service.go

Co-Authored-By: Preston Van Loon <preston@prysmaticlabs.com>

* remove build options

* refactor tests
2019-08-21 11:38:30 +05:30

86 lines
2.2 KiB
Go

package p2p
import (
"crypto/ecdsa"
"fmt"
"net"
"time"
"github.com/ethereum/go-ethereum/p2p/discv5"
"github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
)
// Listener defines the discovery V5 network interface that is used
// to communicate with other peers.
type Listener interface {
Self() *discv5.Node
Close()
Lookup(discv5.NodeID) []*discv5.Node
ReadRandomNodes([]*discv5.Node) int
SetFallbackNodes([]*discv5.Node) error
Resolve(discv5.NodeID) *discv5.Node
RegisterTopic(discv5.Topic, <-chan struct{})
SearchTopic(discv5.Topic, <-chan time.Duration, chan<- *discv5.Node, chan<- bool)
}
func createListener(ipAddr net.IP, port int, privKey *ecdsa.PrivateKey) *discv5.Network {
udpAddr := &net.UDPAddr{
IP: ipAddr,
Port: port,
}
conn, err := net.ListenUDP("udp4", udpAddr)
if err != nil {
log.Fatal(err)
}
network, err := discv5.ListenUDP(privKey, conn, "", nil)
if err != nil {
log.Fatal(err)
}
return network
}
func startDiscoveryV5(addr net.IP, privKey *ecdsa.PrivateKey, cfg *Config) (*discv5.Network, error) {
listener := createListener(addr, int(cfg.UDPPort), privKey)
bootNode, err := discv5.ParseNode(cfg.BootstrapNodeAddr)
if err != nil {
return nil, err
}
if err := listener.SetFallbackNodes([]*discv5.Node{bootNode}); err != nil {
return nil, err
}
node := listener.Self()
log.Infof("Started Discovery: %s", node.String())
return listener, nil
}
func convertToMultiAddr(nodes []*discv5.Node) []ma.Multiaddr {
var multiAddrs []ma.Multiaddr
for _, node := range nodes {
ip4 := node.IP.To4()
if ip4 == nil {
log.Error("Node doesn't have an ip4 address")
continue
}
pubkey, err := node.ID.Pubkey()
if err != nil {
log.Errorf("Could not get pubkey from node ID: %v", err)
continue
}
assertedKey := convertToInterfacePubkey(pubkey)
id, err := peer.IDFromPublicKey(assertedKey)
if err != nil {
log.Errorf("Could not get peer id: %v", err)
}
multiAddrString := fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", ip4.String(), node.TCP, id)
multiAddr, err := ma.NewMultiaddr(multiAddrString)
if err != nil {
log.Errorf("Could not get multiaddr:%v", err)
continue
}
multiAddrs = append(multiAddrs, multiAddr)
}
return multiAddrs
}