mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 23:48:06 -05:00
Update Discv5 to the Latest Version (#3392)
* update workspace * change to new version * gaz * set keys * try more things * finally fixed all tests * fix bootnode * Update beacon-chain/p2p/discovery.go Co-Authored-By: Preston Van Loon <preston@prysmaticlabs.com> * preston's and raul's review * add http server * add tool * add image * change comment * add multiaddr comment * lint * cosmetic changes * fix docker * remove dep * preston's requested changes
This commit is contained in:
@@ -192,7 +192,7 @@ protobuf_deps()
|
|||||||
|
|
||||||
go_repository(
|
go_repository(
|
||||||
name = "com_github_ethereum_go_ethereum",
|
name = "com_github_ethereum_go_ethereum",
|
||||||
commit = "981f27aaf9bdce45391d0cd8bb522df514e0b566",
|
commit = "8839d2f3b900530fbab26154740e8bded3932a86",
|
||||||
importpath = "github.com/ethereum/go-ethereum",
|
importpath = "github.com/ethereum/go-ethereum",
|
||||||
# Note: go-ethereum is not bazel-friendly with regards to cgo. We have a
|
# Note: go-ethereum is not bazel-friendly with regards to cgo. We have a
|
||||||
# a fork that has resolved these issues by disabling HID/USB support and
|
# a fork that has resolved these issues by disabling HID/USB support and
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ go_library(
|
|||||||
"//shared/iputils:go_default_library",
|
"//shared/iputils:go_default_library",
|
||||||
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//crypto:go_default_library",
|
"@com_github_ethereum_go_ethereum//crypto:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//p2p/discv5:go_default_library",
|
"@com_github_ethereum_go_ethereum//p2p/discover:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enr:go_default_library",
|
||||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||||
"@com_github_ipfs_go_ipfs_addr//:go_default_library",
|
"@com_github_ipfs_go_ipfs_addr//:go_default_library",
|
||||||
"@com_github_karlseguin_ccache//:go_default_library",
|
"@com_github_karlseguin_ccache//:go_default_library",
|
||||||
@@ -59,6 +61,7 @@ go_test(
|
|||||||
"service_test.go",
|
"service_test.go",
|
||||||
],
|
],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
|
flaky = True,
|
||||||
tags = ["block-network"],
|
tags = ["block-network"],
|
||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/p2p/testing:go_default_library",
|
"//beacon-chain/p2p/testing:go_default_library",
|
||||||
@@ -66,7 +69,8 @@ go_test(
|
|||||||
"//shared/iputils:go_default_library",
|
"//shared/iputils:go_default_library",
|
||||||
"//shared/testutil:go_default_library",
|
"//shared/testutil:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//crypto:go_default_library",
|
"@com_github_ethereum_go_ethereum//crypto:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//p2p/discv5:go_default_library",
|
"@com_github_ethereum_go_ethereum//p2p/discover:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
|
||||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||||
"@com_github_libp2p_go_libp2p//:go_default_library",
|
"@com_github_libp2p_go_libp2p//:go_default_library",
|
||||||
"@com_github_libp2p_go_libp2p_core//host:go_default_library",
|
"@com_github_libp2p_go_libp2p_core//host:go_default_library",
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import (
|
|||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||||
iaddr "github.com/ipfs/go-ipfs-addr"
|
iaddr "github.com/ipfs/go-ipfs-addr"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
ma "github.com/multiformats/go-multiaddr"
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
@@ -16,48 +17,69 @@ import (
|
|||||||
// Listener defines the discovery V5 network interface that is used
|
// Listener defines the discovery V5 network interface that is used
|
||||||
// to communicate with other peers.
|
// to communicate with other peers.
|
||||||
type Listener interface {
|
type Listener interface {
|
||||||
Self() *discv5.Node
|
Self() *enode.Node
|
||||||
Close()
|
Close()
|
||||||
Lookup(discv5.NodeID) []*discv5.Node
|
Lookup(enode.ID) []*enode.Node
|
||||||
ReadRandomNodes([]*discv5.Node) int
|
ReadRandomNodes([]*enode.Node) int
|
||||||
SetFallbackNodes([]*discv5.Node) error
|
Resolve(*enode.Node) *enode.Node
|
||||||
Resolve(discv5.NodeID) *discv5.Node
|
LookupRandom() []*enode.Node
|
||||||
RegisterTopic(discv5.Topic, <-chan struct{})
|
Ping(*enode.Node) error
|
||||||
SearchTopic(discv5.Topic, <-chan time.Duration, chan<- *discv5.Node, chan<- bool)
|
RequestENR(*enode.Node) (*enode.Node, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createListener(ipAddr net.IP, port int, privKey *ecdsa.PrivateKey) *discv5.Network {
|
func createListener(ipAddr net.IP, privKey *ecdsa.PrivateKey, cfg *Config) *discover.UDPv5 {
|
||||||
udpAddr := &net.UDPAddr{
|
udpAddr := &net.UDPAddr{
|
||||||
IP: ipAddr,
|
IP: ipAddr,
|
||||||
Port: port,
|
Port: int(cfg.Port),
|
||||||
}
|
}
|
||||||
conn, err := net.ListenUDP("udp4", udpAddr)
|
conn, err := net.ListenUDP("udp4", udpAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
localNode, err := createLocalNode(privKey, ipAddr, int(cfg.Port))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
dv5Cfg := discover.Config{
|
||||||
|
PrivateKey: privKey,
|
||||||
|
}
|
||||||
|
if cfg.BootstrapNodeAddr != "" {
|
||||||
|
bootNode, err := enode.Parse(enode.ValidSchemes, cfg.BootstrapNodeAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
dv5Cfg.Bootnodes = []*enode.Node{bootNode}
|
||||||
|
}
|
||||||
|
|
||||||
network, err := discv5.ListenUDP(privKey, conn, "", nil)
|
network, err := discover.ListenV5(conn, localNode, dv5Cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
return network
|
return network
|
||||||
}
|
}
|
||||||
|
|
||||||
func startDiscoveryV5(addr net.IP, privKey *ecdsa.PrivateKey, cfg *Config) (*discv5.Network, error) {
|
func createLocalNode(privKey *ecdsa.PrivateKey, ipAddr net.IP, port int) (*enode.LocalNode, error) {
|
||||||
listener := createListener(addr, int(cfg.Port), privKey)
|
db, err := enode.OpenDB("")
|
||||||
bootNode, err := discv5.ParseNode(cfg.BootstrapNodeAddr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "could not open node's peer database")
|
||||||
}
|
|
||||||
if err := listener.SetFallbackNodes([]*discv5.Node{bootNode}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
localNode := enode.NewLocalNode(db, privKey)
|
||||||
|
ipEntry := enr.IP(ipAddr)
|
||||||
|
udpEntry := enr.UDP(port)
|
||||||
|
localNode.Set(ipEntry)
|
||||||
|
localNode.Set(udpEntry)
|
||||||
|
|
||||||
|
return localNode, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func startDiscoveryV5(addr net.IP, privKey *ecdsa.PrivateKey, cfg *Config) (*discover.UDPv5, error) {
|
||||||
|
listener := createListener(addr, privKey, cfg)
|
||||||
node := listener.Self()
|
node := listener.Self()
|
||||||
log.Infof("Started Discovery: %s", node.String())
|
log.Infof("Started Discovery: %s", node.ID())
|
||||||
return listener, nil
|
return listener, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertToMultiAddr(nodes []*discv5.Node) []ma.Multiaddr {
|
func convertToMultiAddr(nodes []*enode.Node) []ma.Multiaddr {
|
||||||
var multiAddrs []ma.Multiaddr
|
var multiAddrs []ma.Multiaddr
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
multiAddr, err := convertToSingleMultiAddr(node)
|
multiAddr, err := convertToSingleMultiAddr(node)
|
||||||
@@ -70,21 +92,21 @@ func convertToMultiAddr(nodes []*discv5.Node) []ma.Multiaddr {
|
|||||||
return multiAddrs
|
return multiAddrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertToSingleMultiAddr(node *discv5.Node) (ma.Multiaddr, error) {
|
func convertToSingleMultiAddr(node *enode.Node) (ma.Multiaddr, error) {
|
||||||
ip4 := node.IP.To4()
|
ip4 := node.IP().To4()
|
||||||
if ip4 == nil {
|
if ip4 == nil {
|
||||||
return nil, errors.New("node doesn't have an ip4 address")
|
return nil, errors.New("node doesn't have an ip4 address")
|
||||||
}
|
}
|
||||||
pubkey, err := node.ID.Pubkey()
|
pubkey := node.Pubkey()
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "could not get pubkey from node ID")
|
|
||||||
}
|
|
||||||
assertedKey := convertToInterfacePubkey(pubkey)
|
assertedKey := convertToInterfacePubkey(pubkey)
|
||||||
id, err := peer.IDFromPublicKey(assertedKey)
|
id, err := peer.IDFromPublicKey(assertedKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get peer id")
|
return nil, errors.Wrap(err, "could not get peer id")
|
||||||
}
|
}
|
||||||
multiAddrString := fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", ip4.String(), node.TCP, id)
|
// we use the udp port for now, since all udp and tcp connections occur from the same
|
||||||
|
// port. This will be changed to the node's TCP port in the future, when we allow a
|
||||||
|
// beacon node to provide separate TCP and UDP ports.
|
||||||
|
multiAddrString := fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", ip4.String(), node.UDP(), id)
|
||||||
multiAddr, err := ma.NewMultiaddr(multiAddrString)
|
multiAddr, err := ma.NewMultiaddr(multiAddrString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get multiaddr")
|
return nil, errors.Wrap(err, "could not get multiaddr")
|
||||||
|
|||||||
@@ -2,20 +2,21 @@ package p2p
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
"github.com/prysmaticlabs/prysm/shared/iputils"
|
"github.com/prysmaticlabs/prysm/shared/iputils"
|
||||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var discoveryWaitTime = 1 * time.Second
|
||||||
|
|
||||||
func createAddrAndPrivKey(t *testing.T) (net.IP, *ecdsa.PrivateKey) {
|
func createAddrAndPrivKey(t *testing.T) (net.IP, *ecdsa.PrivateKey) {
|
||||||
ip, err := iputils.ExternalIPv4()
|
ip, err := iputils.ExternalIPv4()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -32,20 +33,17 @@ func createAddrAndPrivKey(t *testing.T) (net.IP, *ecdsa.PrivateKey) {
|
|||||||
func TestCreateListener(t *testing.T) {
|
func TestCreateListener(t *testing.T) {
|
||||||
port := 1024
|
port := 1024
|
||||||
ipAddr, pkey := createAddrAndPrivKey(t)
|
ipAddr, pkey := createAddrAndPrivKey(t)
|
||||||
listener := createListener(ipAddr, port, pkey)
|
listener := createListener(ipAddr, pkey, &Config{Port: uint(port)})
|
||||||
defer listener.Close()
|
defer listener.Close()
|
||||||
|
|
||||||
if !listener.Self().IP.Equal(ipAddr) {
|
if !listener.Self().IP().Equal(ipAddr) {
|
||||||
t.Errorf("Ip address is not the expected type, wanted %s but got %s", ipAddr.String(), listener.Self().IP.String())
|
t.Errorf("Ip address is not the expected type, wanted %s but got %s", ipAddr.String(), listener.Self().IP().String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if port != int(listener.Self().UDP) {
|
if port != int(listener.Self().UDP()) {
|
||||||
t.Errorf("In correct port number, wanted %d but got %d", port, listener.Self().UDP)
|
t.Errorf("In correct port number, wanted %d but got %d", port, listener.Self().UDP())
|
||||||
}
|
|
||||||
pubkey, err := listener.Self().ID.Pubkey()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
}
|
||||||
|
pubkey := listener.Self().Pubkey()
|
||||||
XisSame := pkey.PublicKey.X.Cmp(pubkey.X) == 0
|
XisSame := pkey.PublicKey.X.Cmp(pubkey.X) == 0
|
||||||
YisSame := pkey.PublicKey.Y.Cmp(pubkey.Y) == 0
|
YisSame := pkey.PublicKey.Y.Cmp(pubkey.Y) == 0
|
||||||
|
|
||||||
@@ -57,20 +55,19 @@ func TestCreateListener(t *testing.T) {
|
|||||||
func TestStartDiscV5_DiscoverAllPeers(t *testing.T) {
|
func TestStartDiscV5_DiscoverAllPeers(t *testing.T) {
|
||||||
port := 2000
|
port := 2000
|
||||||
ipAddr, pkey := createAddrAndPrivKey(t)
|
ipAddr, pkey := createAddrAndPrivKey(t)
|
||||||
bootListener := createListener(ipAddr, port, pkey)
|
bootListener := createListener(ipAddr, pkey, &Config{Port: uint(port)})
|
||||||
defer bootListener.Close()
|
defer bootListener.Close()
|
||||||
|
|
||||||
bootNode := bootListener.Self()
|
bootNode := bootListener.Self()
|
||||||
|
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
BootstrapNodeAddr: bootNode.String(),
|
BootstrapNodeAddr: bootNode.String(),
|
||||||
Encoding: "ssz",
|
Encoding: "ssz",
|
||||||
}
|
}
|
||||||
|
|
||||||
var listeners []*discv5.Network
|
var listeners []*discover.UDPv5
|
||||||
for i := 1; i <= 5; i++ {
|
for i := 1; i <= 5; i++ {
|
||||||
port = 2000 + i
|
port = 3000 + i
|
||||||
cfg.UDPPort = uint(port)
|
cfg.Port = uint(port)
|
||||||
ipAddr, pkey := createAddrAndPrivKey(t)
|
ipAddr, pkey := createAddrAndPrivKey(t)
|
||||||
listener, err := startDiscoveryV5(ipAddr, pkey, cfg)
|
listener, err := startDiscoveryV5(ipAddr, pkey, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -80,13 +77,13 @@ func TestStartDiscV5_DiscoverAllPeers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the nodes to have their local routing tables to be populated with the other nodes
|
// Wait for the nodes to have their local routing tables to be populated with the other nodes
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(discoveryWaitTime)
|
||||||
|
|
||||||
lastListener := listeners[len(listeners)-1]
|
lastListener := listeners[len(listeners)-1]
|
||||||
nodes := lastListener.Lookup(bootNode.ID)
|
nodes := lastListener.Lookup(bootNode.ID())
|
||||||
if len(nodes) != 6 {
|
if len(nodes) < 4 {
|
||||||
t.Errorf("The node's local table doesn't have the expected number of nodes. "+
|
t.Errorf("The node's local table doesn't have the expected number of nodes. "+
|
||||||
"Expected %d but got %d", 6, len(nodes))
|
"Expected more than or equal to %d but got %d", 4, len(nodes))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close all ports
|
// Close all ports
|
||||||
@@ -98,24 +95,21 @@ func TestStartDiscV5_DiscoverAllPeers(t *testing.T) {
|
|||||||
func TestMultiAddrsConversion_InvalidIPAddr(t *testing.T) {
|
func TestMultiAddrsConversion_InvalidIPAddr(t *testing.T) {
|
||||||
hook := logTest.NewGlobal()
|
hook := logTest.NewGlobal()
|
||||||
ipAddr := net.IPv6zero
|
ipAddr := net.IPv6zero
|
||||||
pkey, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader)
|
_, pkey := createAddrAndPrivKey(t)
|
||||||
|
node, err := createLocalNode(pkey, ipAddr, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Could not generate key %v", err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
nodeID := discv5.PubkeyID(&pkey.PublicKey)
|
_ = convertToMultiAddr([]*enode.Node{node.Node()})
|
||||||
node := discv5.NewNode(nodeID, ipAddr, 0, 0)
|
|
||||||
_ = convertToMultiAddr([]*discv5.Node{node})
|
|
||||||
|
|
||||||
testutil.AssertLogsContain(t, hook, "node doesn't have an ip4 address")
|
testutil.AssertLogsContain(t, hook, "node doesn't have an ip4 address")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultiAddrConversion_OK(t *testing.T) {
|
func TestMultiAddrConversion_OK(t *testing.T) {
|
||||||
hook := logTest.NewGlobal()
|
hook := logTest.NewGlobal()
|
||||||
port := 1024
|
|
||||||
ipAddr, pkey := createAddrAndPrivKey(t)
|
ipAddr, pkey := createAddrAndPrivKey(t)
|
||||||
listener := createListener(ipAddr, port, pkey)
|
listener := createListener(ipAddr, pkey, &Config{})
|
||||||
|
|
||||||
_ = convertToMultiAddr([]*discv5.Node{listener.Self()})
|
_ = convertToMultiAddr([]*enode.Node{listener.Self()})
|
||||||
testutil.AssertLogsDoNotContain(t, hook, "Node doesn't have an ip4 address")
|
testutil.AssertLogsDoNotContain(t, hook, "Node doesn't have an ip4 address")
|
||||||
testutil.AssertLogsDoNotContain(t, hook, "Invalid port, the tcp port of the node is a reserved port")
|
testutil.AssertLogsDoNotContain(t, hook, "Invalid port, the tcp port of the node is a reserved port")
|
||||||
testutil.AssertLogsDoNotContain(t, hook, "Could not get multiaddr")
|
testutil.AssertLogsDoNotContain(t, hook, "Could not get multiaddr")
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/karlseguin/ccache"
|
"github.com/karlseguin/ccache"
|
||||||
"github.com/libp2p/go-libp2p"
|
"github.com/libp2p/go-libp2p"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
@@ -92,7 +92,6 @@ func (s *Service) Start() {
|
|||||||
|
|
||||||
if s.cfg.BootstrapNodeAddr != "" && !s.cfg.NoDiscovery {
|
if s.cfg.BootstrapNodeAddr != "" && !s.cfg.NoDiscovery {
|
||||||
ipAddr := ipAddr(s.cfg)
|
ipAddr := ipAddr(s.cfg)
|
||||||
|
|
||||||
listener, err := startDiscoveryV5(ipAddr, s.privKey, s.cfg)
|
listener, err := startDiscoveryV5(ipAddr, s.privKey, s.cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("Failed to start discovery")
|
log.WithError(err).Error("Failed to start discovery")
|
||||||
@@ -184,13 +183,12 @@ func (s *Service) Disconnect(pid peer.ID) error {
|
|||||||
|
|
||||||
// listen for new nodes watches for new nodes in the network and adds them to the peerstore.
|
// listen for new nodes watches for new nodes in the network and adds them to the peerstore.
|
||||||
func (s *Service) listenForNewNodes() {
|
func (s *Service) listenForNewNodes() {
|
||||||
nodes := make([]*discv5.Node, 10)
|
|
||||||
ticker := time.NewTicker(pollingPeriod)
|
ticker := time.NewTicker(pollingPeriod)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
num := s.dv5Listener.ReadRandomNodes(nodes)
|
nodes := s.dv5Listener.LookupRandom()
|
||||||
multiAddresses := convertToMultiAddr(nodes[:num])
|
multiAddresses := convertToMultiAddr(nodes)
|
||||||
s.connectWithAllPeers(multiAddresses)
|
s.connectWithAllPeers(multiAddresses)
|
||||||
case <-s.ctx.Done():
|
case <-s.ctx.Done():
|
||||||
log.Debug("p2p context is closed, exiting routine")
|
log.Debug("p2p context is closed, exiting routine")
|
||||||
@@ -221,7 +219,7 @@ func (s *Service) connectWithAllPeers(multiAddrs []ma.Multiaddr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) addBootNodeToExclusionList() error {
|
func (s *Service) addBootNodeToExclusionList() error {
|
||||||
bootNode, err := discv5.ParseNode(s.cfg.BootstrapNodeAddr)
|
bootNode, err := enode.Parse(enode.ValidSchemes, s.cfg.BootstrapNodeAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
libp2p "github.com/libp2p/go-libp2p"
|
libp2p "github.com/libp2p/go-libp2p"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
@@ -19,35 +20,35 @@ import (
|
|||||||
|
|
||||||
type mockListener struct{}
|
type mockListener struct{}
|
||||||
|
|
||||||
func (m *mockListener) Self() *discv5.Node {
|
func (mockListener) Self() *enode.Node {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockListener) Close() {
|
func (mockListener) Close() {
|
||||||
//no-op
|
//no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockListener) Lookup(discv5.NodeID) []*discv5.Node {
|
func (mockListener) Lookup(enode.ID) []*enode.Node {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockListener) ReadRandomNodes([]*discv5.Node) int {
|
func (mockListener) ReadRandomNodes([]*enode.Node) int {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockListener) SetFallbackNodes([]*discv5.Node) error {
|
func (mockListener) Resolve(*enode.Node) *enode.Node {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockListener) Resolve(discv5.NodeID) *discv5.Node {
|
func (mockListener) LookupRandom() []*enode.Node {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockListener) RegisterTopic(discv5.Topic, <-chan struct{}) {
|
func (mockListener) Ping(*enode.Node) error {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockListener) SearchTopic(discv5.Topic, <-chan time.Duration, chan<- *discv5.Node, chan<- bool) {
|
func (mockListener) RequestENR(*enode.Node) (*enode.Node, error) {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,24 +122,26 @@ func TestService_Status_NotRunning(t *testing.T) {
|
|||||||
|
|
||||||
func TestListenForNewNodes(t *testing.T) {
|
func TestListenForNewNodes(t *testing.T) {
|
||||||
// setup bootnode
|
// setup bootnode
|
||||||
|
cfg := &Config{}
|
||||||
port := 2000
|
port := 2000
|
||||||
|
cfg.Port = uint(port)
|
||||||
_, pkey := createAddrAndPrivKey(t)
|
_, pkey := createAddrAndPrivKey(t)
|
||||||
ipAddr := net.ParseIP("127.0.0.1")
|
ipAddr := net.ParseIP("127.0.0.1")
|
||||||
bootListener := createListener(ipAddr, port, pkey)
|
bootListener := createListener(ipAddr, pkey, cfg)
|
||||||
defer bootListener.Close()
|
defer bootListener.Close()
|
||||||
|
|
||||||
bootNode := bootListener.Self()
|
bootNode := bootListener.Self()
|
||||||
|
|
||||||
cfg := &Config{
|
cfg = &Config{
|
||||||
BootstrapNodeAddr: bootNode.String(),
|
BootstrapNodeAddr: bootNode.String(),
|
||||||
Encoding: "ssz",
|
Encoding: "ssz",
|
||||||
}
|
}
|
||||||
var listeners []*discv5.Network
|
var listeners []*discover.UDPv5
|
||||||
var hosts []host.Host
|
var hosts []host.Host
|
||||||
// setup other nodes
|
// setup other nodes
|
||||||
for i := 1; i <= 5; i++ {
|
for i := 1; i <= 5; i++ {
|
||||||
listener, h := createPeer(t, cfg, port+i)
|
listener, h := createPeer(t, cfg, port+i)
|
||||||
listeners = append(listeners, listener.(*discv5.Network))
|
listeners = append(listeners, listener.(*discover.UDPv5))
|
||||||
hosts = append(hosts, h)
|
hosts = append(hosts, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +163,7 @@ func TestListenForNewNodes(t *testing.T) {
|
|||||||
s.Start()
|
s.Start()
|
||||||
defer s.Stop()
|
defer s.Stop()
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(4 * time.Second)
|
||||||
peers := s.host.Network().Peers()
|
peers := s.host.Network().Peers()
|
||||||
if len(peers) != 5 {
|
if len(peers) != 5 {
|
||||||
t.Errorf("Not all peers added to peerstore, wanted %d but got %d", 5, len(peers))
|
t.Errorf("Not all peers added to peerstore, wanted %d but got %d", 5, len(peers))
|
||||||
|
|||||||
@@ -11,8 +11,11 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//shared/version:go_default_library",
|
"//shared/version:go_default_library",
|
||||||
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//p2p/discv5:go_default_library",
|
"@com_github_ethereum_go_ethereum//p2p/discover:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enr:go_default_library",
|
||||||
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
||||||
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@org_uber_go_automaxprocs//:go_default_library",
|
"@org_uber_go_automaxprocs//:go_default_library",
|
||||||
],
|
],
|
||||||
@@ -32,8 +35,11 @@ go_image(
|
|||||||
deps = [
|
deps = [
|
||||||
"//shared/version:go_default_library",
|
"//shared/version:go_default_library",
|
||||||
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//p2p/discv5:go_default_library",
|
"@com_github_ethereum_go_ethereum//p2p/discover:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enr:go_default_library",
|
||||||
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
||||||
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@org_uber_go_automaxprocs//:go_default_library",
|
"@org_uber_go_automaxprocs//:go_default_library",
|
||||||
],
|
],
|
||||||
@@ -64,10 +70,12 @@ go_test(
|
|||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = ["bootnode_test.go"],
|
srcs = ["bootnode_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
|
flaky = True,
|
||||||
deps = [
|
deps = [
|
||||||
"//shared/iputils:go_default_library",
|
"//shared/iputils:go_default_library",
|
||||||
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//p2p/discv5:go_default_library",
|
"@com_github_ethereum_go_ethereum//p2p/discover:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
|
||||||
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
||||||
"@org_uber_go_automaxprocs//:go_default_library",
|
"@org_uber_go_automaxprocs//:go_default_library",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -17,8 +17,11 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||||
"github.com/libp2p/go-libp2p-core/crypto"
|
"github.com/libp2p/go-libp2p-core/crypto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/prysm/shared/version"
|
"github.com/prysmaticlabs/prysm/shared/version"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
_ "go.uber.org/automaxprocs"
|
_ "go.uber.org/automaxprocs"
|
||||||
@@ -28,7 +31,7 @@ var (
|
|||||||
debug = flag.Bool("debug", false, "Enable debug logging")
|
debug = flag.Bool("debug", false, "Enable debug logging")
|
||||||
privateKey = flag.String("private", "", "Private key to use for peer ID")
|
privateKey = flag.String("private", "", "Private key to use for peer ID")
|
||||||
port = flag.Int("port", 4000, "Port to listen for connections")
|
port = flag.Int("port", 4000, "Port to listen for connections")
|
||||||
externalIP = flag.String("external-ip", "0.0.0.0", "External IP for the bootnode")
|
externalIP = flag.String("external-ip", "127.0.0.1", "External IP for the bootnode")
|
||||||
|
|
||||||
log = logrus.WithField("prefix", "bootnode")
|
log = logrus.WithField("prefix", "bootnode")
|
||||||
)
|
)
|
||||||
@@ -41,37 +44,57 @@ func main() {
|
|||||||
if *debug {
|
if *debug {
|
||||||
logrus.SetLevel(logrus.DebugLevel)
|
logrus.SetLevel(logrus.DebugLevel)
|
||||||
}
|
}
|
||||||
|
cfg := discover.Config{
|
||||||
privKey := extractPrivateKey()
|
PrivateKey: extractPrivateKey(),
|
||||||
listener := createListener(*externalIP, *port, privKey)
|
}
|
||||||
|
listener := createListener(*externalIP, *port, cfg)
|
||||||
|
|
||||||
node := listener.Self()
|
node := listener.Self()
|
||||||
log.Infof("Running bootnode, url: %s", node.String())
|
log.Infof("Running bootnode: %s", node.String())
|
||||||
|
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createListener(ipAddr string, port int, privKey *ecdsa.PrivateKey) *discv5.Network {
|
func createListener(ipAddr string, port int, cfg discover.Config) *discover.UDPv5 {
|
||||||
ip := net.ParseIP(ipAddr)
|
ip := net.ParseIP(ipAddr)
|
||||||
if ip.To4() == nil {
|
if ip.To4() == nil {
|
||||||
log.Fatalf("IPV4 address not provided instead %s was provided", ipAddr)
|
log.Fatalf("IPV4 address not provided instead %s was provided", ipAddr)
|
||||||
}
|
}
|
||||||
udpAddr := &net.UDPAddr{
|
udpAddr := &net.UDPAddr{
|
||||||
IP: net.ParseIP(ipAddr),
|
IP: ip,
|
||||||
Port: port,
|
Port: port,
|
||||||
}
|
}
|
||||||
conn, err := net.ListenUDP("udp4", udpAddr)
|
conn, err := net.ListenUDP("udp4", udpAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
localNode, err := createLocalNode(cfg.PrivateKey, ip, port)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
network, err := discv5.ListenUDP(privKey, conn, "", nil)
|
network, err := discover.ListenV5(conn, localNode, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
return network
|
return network
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createLocalNode(privKey *ecdsa.PrivateKey, ipAddr net.IP, port int) (*enode.LocalNode, error) {
|
||||||
|
db, err := enode.OpenDB("")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Could not open node's peer database")
|
||||||
|
}
|
||||||
|
|
||||||
|
localNode := enode.NewLocalNode(db, privKey)
|
||||||
|
ipEntry := enr.IP(ipAddr)
|
||||||
|
udpEntry := enr.UDP(port)
|
||||||
|
localNode.Set(ipEntry)
|
||||||
|
localNode.Set(udpEntry)
|
||||||
|
|
||||||
|
return localNode, nil
|
||||||
|
}
|
||||||
|
|
||||||
func extractPrivateKey() *ecdsa.PrivateKey {
|
func extractPrivateKey() *ecdsa.PrivateKey {
|
||||||
var privKey *ecdsa.PrivateKey
|
var privKey *ecdsa.PrivateKey
|
||||||
if *privateKey != "" {
|
if *privateKey != "" {
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import (
|
|||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/libp2p/go-libp2p-core/crypto"
|
"github.com/libp2p/go-libp2p-core/crypto"
|
||||||
"github.com/prysmaticlabs/prysm/shared/iputils"
|
"github.com/prysmaticlabs/prysm/shared/iputils"
|
||||||
_ "go.uber.org/automaxprocs"
|
_ "go.uber.org/automaxprocs"
|
||||||
@@ -17,44 +19,43 @@ func TestBootnode_OK(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
privKey := extractPrivateKey()
|
cfg := discover.Config{
|
||||||
listener := createListener(ipAddr, 4000, privKey)
|
PrivateKey: extractPrivateKey(),
|
||||||
|
}
|
||||||
|
listener := createListener(ipAddr, 4000, cfg)
|
||||||
defer listener.Close()
|
defer listener.Close()
|
||||||
|
|
||||||
privKey = extractPrivateKey()
|
cfg.PrivateKey = extractPrivateKey()
|
||||||
listener2 := createListener(ipAddr, 4001, privKey)
|
bootNode, err := enode.Parse(enode.ValidSchemes, listener.Self().String())
|
||||||
defer listener.Close()
|
|
||||||
|
|
||||||
err = listener.SetFallbackNodes([]*discv5.Node{listener2.Self()})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = listener2.SetFallbackNodes([]*discv5.Node{listener.Self()})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
cfg.Bootnodes = []*enode.Node{bootNode}
|
||||||
|
listener2 := createListener(ipAddr, 4001, cfg)
|
||||||
|
defer listener2.Close()
|
||||||
|
|
||||||
// test that both the nodes have the other peer stored in their local table.
|
// test that both the nodes have the other peer stored in their local table.
|
||||||
listenerNode := listener.Self()
|
listenerNode := listener.Self()
|
||||||
listenerNode2 := listener2.Self()
|
listenerNode2 := listener2.Self()
|
||||||
|
|
||||||
nodes := listener.Lookup(listenerNode2.ID)
|
time.Sleep(1 * time.Second)
|
||||||
if len(nodes) != 2 {
|
|
||||||
t.Errorf("Length of nodes stored in table is not expected. Wanted %d but got %d", 2, len(nodes))
|
nodes := listener.Lookup(listenerNode2.ID())
|
||||||
|
if len(nodes) == 0 {
|
||||||
|
t.Fatalf("Length of nodes stored in table is not expected. Wanted to be more than %d but got %d", 0, len(nodes))
|
||||||
|
|
||||||
}
|
}
|
||||||
if nodes[0].ID != listenerNode2.ID {
|
if nodes[0].ID() != listenerNode2.ID() {
|
||||||
t.Errorf("Wanted node ID of %s but got %s", listenerNode2.ID, nodes[1].ID)
|
t.Errorf("Wanted node ID of %s but got %s", listenerNode2.ID(), nodes[1].ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = listener2.Lookup(listenerNode.ID)
|
nodes = listener2.Lookup(listenerNode.ID())
|
||||||
if len(nodes) != 2 {
|
if len(nodes) == 0 {
|
||||||
t.Errorf("Length of nodes stored in table is not expected. Wanted %d but got %d", 2, len(nodes))
|
t.Errorf("Length of nodes stored in table is not expected. Wanted to be more than %d but got %d", 0, len(nodes))
|
||||||
|
|
||||||
}
|
}
|
||||||
if nodes[0].ID != listenerNode.ID {
|
if nodes[0].ID() != listenerNode.ID() {
|
||||||
t.Errorf("Wanted node ID of %s but got %s", listenerNode.ID, nodes[1].ID)
|
t.Errorf("Wanted node ID of %s but got %s", listenerNode.ID(), nodes[1].ID())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
61
tools/enr-calculator/BUILD.bazel
Normal file
61
tools/enr-calculator/BUILD.bazel
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
|
||||||
|
load("@io_bazel_rules_docker//go:image.bzl", "go_image")
|
||||||
|
load("@io_bazel_rules_docker//container:container.bzl", "container_bundle")
|
||||||
|
load("@io_bazel_rules_docker//contrib:push-all.bzl", "docker_push")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["main.go"],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/tools/enr-calculator",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = [
|
||||||
|
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enr:go_default_library",
|
||||||
|
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
||||||
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
|
"@org_uber_go_automaxprocs//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_binary(
|
||||||
|
name = "enr-calculator",
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_image(
|
||||||
|
name = "image",
|
||||||
|
srcs = ["main.go"],
|
||||||
|
goarch = "amd64",
|
||||||
|
goos = "linux",
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/tools/enr-calculator",
|
||||||
|
pure = "on",
|
||||||
|
race = "off",
|
||||||
|
static = "on",
|
||||||
|
tags = ["manual"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = [
|
||||||
|
"@com_github_btcsuite_btcd//btcec:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
|
||||||
|
"@com_github_ethereum_go_ethereum//p2p/enr:go_default_library",
|
||||||
|
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
||||||
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
|
"@org_uber_go_automaxprocs//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
container_bundle(
|
||||||
|
name = "image_bundle",
|
||||||
|
images = {
|
||||||
|
"gcr.io/prysmaticlabs/prysm/enr-calculator:latest": ":image",
|
||||||
|
"gcr.io/prysmaticlabs/prysm/enr-calculator:{DOCKER_TAG}": ":image",
|
||||||
|
},
|
||||||
|
tags = ["manual"],
|
||||||
|
)
|
||||||
|
|
||||||
|
docker_push(
|
||||||
|
name = "push_images",
|
||||||
|
bundle = ":image_bundle",
|
||||||
|
tags = ["manual"],
|
||||||
|
)
|
||||||
16
tools/enr-calculator/README.md
Normal file
16
tools/enr-calculator/README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# ENR Calculator
|
||||||
|
|
||||||
|
To generate the ENR of a node
|
||||||
|
|
||||||
|
```
|
||||||
|
bazel run //tools/enr-calculator:enr-calculator -- --private CAISIJXSWjkbgprwuo01QCRegULoNIOZ0yTl1fLz5N0SsJCS --ipAddress 127.0.0.1 --port 2000
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
This will deterministically generate an ENR from given inputs of private key, ip address and udp port.
|
||||||
|
|
||||||
|
Output of the above command:
|
||||||
|
```
|
||||||
|
INFO[0000] enr:-IS4QKk3gX9EqxA3x83AbCiyAnSuPDMvK52dC50Hm1XGDd5tEyQhM3VcJL-4b8kDg5APz_povv0Syqk0nancoNW-cq0BgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQM1E5yUsp9vDQj1tv3ZWXCvaFBvrPNdz8KPI1NhxfQWzIN1ZHCCB9A
|
||||||
|
|
||||||
|
```
|
||||||
64
tools/enr-calculator/main.go
Normal file
64
tools/enr-calculator/main.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
// This binary is a simple rest API endpoint to calculate
|
||||||
|
// the ENR value of a node given its private key,ip address and port.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"flag"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/btcec"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||||
|
"github.com/libp2p/go-libp2p-core/crypto"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
_ "go.uber.org/automaxprocs"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
privateKey = flag.String("private", "", "Base-64 encoded Private key to use for calculation of ENR")
|
||||||
|
port = flag.Int("port", 0, "Port to use for calculation of ENR")
|
||||||
|
ipAddr = flag.String("ipAddress", "", "IP to use in calculation of ENR")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if len(*privateKey) == 0 {
|
||||||
|
log.Fatal("No private key given")
|
||||||
|
}
|
||||||
|
decodedKey, err := crypto.ConfigDecodeKey(*privateKey)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to decode private key: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
privatekey, err := crypto.UnmarshalPrivateKey(decodedKey)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to unmarshal private key: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ecdsaPrivKey := (*ecdsa.PrivateKey)((*btcec.PrivateKey)(privatekey.(*crypto.Secp256k1PrivateKey)))
|
||||||
|
|
||||||
|
if net.ParseIP(*ipAddr).To4() == nil {
|
||||||
|
log.Fatalf("Invalid ipv4 address given: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *port == 0 {
|
||||||
|
log.Fatalf("Invalid udp port given: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := enode.OpenDB("")
|
||||||
|
defer db.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Could not open node's peer database: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
localNode := enode.NewLocalNode(db, ecdsaPrivKey)
|
||||||
|
ipEntry := enr.IP(net.ParseIP(*ipAddr))
|
||||||
|
udpEntry := enr.UDP(*port)
|
||||||
|
localNode.Set(ipEntry)
|
||||||
|
localNode.Set(udpEntry)
|
||||||
|
log.Info(localNode.Node().String())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user