mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Add Back Kademlia DHT to Prysm (#3557)
* serve nodes * remove testing flag * add back bootnode * add dht * add back dht * gaz * fix build * bootnode works in runtime * fix all references * all tests pass * remove feature flag * separate out ports * lint * fix docker build * use one error package
This commit is contained in:
committed by
Preston Van Loon
parent
5294a6c5af
commit
b5b10a8d35
@@ -218,19 +218,21 @@ func (b *BeaconNode) startDB(ctx *cli.Context) error {
|
||||
|
||||
func (b *BeaconNode) registerP2P(ctx *cli.Context) error {
|
||||
// Bootnode ENR may be a filepath to an ENR file.
|
||||
bootnodeENR := ctx.GlobalString(cmd.BootstrapNode.Name)
|
||||
if filepath.Ext(bootnodeENR) == ".enr" {
|
||||
b, err := ioutil.ReadFile(bootnodeENR)
|
||||
if err != nil {
|
||||
return err
|
||||
bootnodeAddrs := sliceutil.SplitCommaSeparated(ctx.GlobalStringSlice(cmd.BootstrapNode.Name))
|
||||
for i, addr := range bootnodeAddrs {
|
||||
if filepath.Ext(addr) == ".enr" {
|
||||
b, err := ioutil.ReadFile(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bootnodeAddrs[i] = string(b)
|
||||
}
|
||||
bootnodeENR = string(b)
|
||||
}
|
||||
|
||||
svc, err := p2p.NewService(&p2p.Config{
|
||||
NoDiscovery: ctx.GlobalBool(cmd.NoDiscovery.Name),
|
||||
StaticPeers: sliceutil.SplitCommaSeparated(ctx.GlobalStringSlice(cmd.StaticPeers.Name)),
|
||||
BootstrapNodeAddr: bootnodeENR,
|
||||
BootstrapNodeAddr: bootnodeAddrs,
|
||||
RelayNodeAddr: ctx.GlobalString(cmd.RelayNode.Name),
|
||||
DataDir: ctx.GlobalString(cmd.DataDirFlag.Name),
|
||||
HostAddress: ctx.GlobalString(cmd.P2PHost.Name),
|
||||
|
||||
@@ -32,14 +32,20 @@ go_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_ipfs_go_datastore//:go_default_library",
|
||||
"@com_github_ipfs_go_datastore//sync:go_default_library",
|
||||
"@com_github_ipfs_go_ipfs_addr//:go_default_library",
|
||||
"@com_github_karlseguin_ccache//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p//p2p/host/routed:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//host:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//network:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//peer:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//protocol:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_kad_dht//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_kad_dht//opts:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_pubsub//:go_default_library",
|
||||
"@com_github_multiformats_go_multiaddr//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
|
||||
@@ -3,17 +3,19 @@ package p2p
|
||||
// Config for the p2p service. These parameters are set from application level flags
|
||||
// to initialize the p2p service.
|
||||
type Config struct {
|
||||
NoDiscovery bool
|
||||
StaticPeers []string
|
||||
BootstrapNodeAddr string
|
||||
RelayNodeAddr string
|
||||
HostAddress string
|
||||
PrivateKey string
|
||||
DataDir string
|
||||
TCPPort uint
|
||||
UDPPort uint
|
||||
MaxPeers uint
|
||||
WhitelistCIDR string
|
||||
EnableUPnP bool
|
||||
Encoding string
|
||||
NoDiscovery bool
|
||||
StaticPeers []string
|
||||
BootstrapNodeAddr []string
|
||||
KademliaBootStrapAddr []string
|
||||
Discv5BootStrapAddr []string
|
||||
RelayNodeAddr string
|
||||
HostAddress string
|
||||
PrivateKey string
|
||||
DataDir string
|
||||
TCPPort uint
|
||||
UDPPort uint
|
||||
MaxPeers uint
|
||||
WhitelistCIDR string
|
||||
EnableUPnP bool
|
||||
Encoding string
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
iaddr "github.com/ipfs/go-ipfs-addr"
|
||||
core "github.com/libp2p/go-libp2p-core"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"github.com/pkg/errors"
|
||||
@@ -43,12 +45,13 @@ func createListener(ipAddr net.IP, privKey *ecdsa.PrivateKey, cfg *Config) *disc
|
||||
dv5Cfg := discover.Config{
|
||||
PrivateKey: privKey,
|
||||
}
|
||||
if cfg.BootstrapNodeAddr != "" {
|
||||
bootNode, err := enode.Parse(enode.ValidSchemes, cfg.BootstrapNodeAddr)
|
||||
dv5Cfg.Bootnodes = []*enode.Node{}
|
||||
for _, addr := range cfg.Discv5BootStrapAddr {
|
||||
bootNode, err := enode.Parse(enode.ValidSchemes, addr)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
dv5Cfg.Bootnodes = []*enode.Node{bootNode}
|
||||
dv5Cfg.Bootnodes = append(dv5Cfg.Bootnodes, bootNode)
|
||||
}
|
||||
|
||||
network, err := discover.ListenV5(conn, localNode, dv5Cfg)
|
||||
@@ -81,6 +84,37 @@ func startDiscoveryV5(addr net.IP, privKey *ecdsa.PrivateKey, cfg *Config) (*dis
|
||||
return listener, nil
|
||||
}
|
||||
|
||||
// startDHTDiscovery supports discovery via DHT.
|
||||
func startDHTDiscovery(host core.Host, bootstrapAddr string) error {
|
||||
multiAddr, err := multiAddrFromString(bootstrapAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
peerInfo, err := peer.AddrInfoFromP2pAddr(multiAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = host.Connect(context.Background(), *peerInfo)
|
||||
return err
|
||||
}
|
||||
|
||||
func parseBootStrapAddrs(addrs []string) (discv5Nodes []string, kadDHTNodes []string) {
|
||||
for _, addr := range addrs {
|
||||
_, err := enode.Parse(enode.ValidSchemes, addr)
|
||||
if err == nil {
|
||||
discv5Nodes = append(discv5Nodes, addr)
|
||||
continue
|
||||
}
|
||||
_, err = multiAddrFromString(addr)
|
||||
if err == nil {
|
||||
kadDHTNodes = append(kadDHTNodes, addr)
|
||||
continue
|
||||
}
|
||||
log.Errorf("Invalid bootstrap address of %s provided", addr)
|
||||
}
|
||||
return discv5Nodes, kadDHTNodes
|
||||
}
|
||||
|
||||
func convertToMultiAddr(nodes []*enode.Node) []ma.Multiaddr {
|
||||
var multiAddrs []ma.Multiaddr
|
||||
for _, node := range nodes {
|
||||
|
||||
@@ -75,8 +75,8 @@ func TestStartDiscV5_DiscoverAllPeers(t *testing.T) {
|
||||
|
||||
bootNode := bootListener.Self()
|
||||
cfg := &Config{
|
||||
BootstrapNodeAddr: bootNode.String(),
|
||||
Encoding: "ssz",
|
||||
Discv5BootStrapAddr: []string{bootNode.String()},
|
||||
Encoding: "ssz",
|
||||
}
|
||||
|
||||
var listeners []*discover.UDPv5
|
||||
|
||||
@@ -7,13 +7,18 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
ds "github.com/ipfs/go-datastore"
|
||||
dsync "github.com/ipfs/go-datastore/sync"
|
||||
"github.com/karlseguin/ccache"
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p-core/protocol"
|
||||
kaddht "github.com/libp2p/go-libp2p-kad-dht"
|
||||
dhtopts "github.com/libp2p/go-libp2p-kad-dht/opts"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
rhost "github.com/libp2p/go-libp2p/p2p/host/routed"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/encoder"
|
||||
@@ -23,9 +28,10 @@ import (
|
||||
var _ = shared.Service(&Service{})
|
||||
|
||||
var pollingPeriod = 1 * time.Second
|
||||
var bootnodePingPeriod = 5 * time.Minute
|
||||
var ttl = 1 * time.Hour
|
||||
|
||||
const prysmProtocolPrefix = "/prysm/0.0.0"
|
||||
|
||||
// Service for managing peer to peer (p2p) networking.
|
||||
type Service struct {
|
||||
ctx context.Context
|
||||
@@ -53,6 +59,11 @@ func NewService(cfg *Config) (*Service, error) {
|
||||
exclusionList: ccache.New(ccache.Configure()),
|
||||
}
|
||||
|
||||
dv5Nodes, kadDHTNodes := parseBootStrapAddrs(s.cfg.BootstrapNodeAddr)
|
||||
|
||||
cfg.Discv5BootStrapAddr = dv5Nodes
|
||||
cfg.KademliaBootStrapAddr = kadDHTNodes
|
||||
|
||||
ipAddr := ipAddr(s.cfg)
|
||||
s.privKey, err = privKey(s.cfg)
|
||||
if err != nil {
|
||||
@@ -67,6 +78,23 @@ func NewService(cfg *Config) (*Service, error) {
|
||||
log.WithError(err).Error("Failed to create p2p host")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(cfg.KademliaBootStrapAddr) != 0 {
|
||||
dopts := []dhtopts.Option{
|
||||
dhtopts.Datastore(dsync.MutexWrap(ds.NewMapDatastore())),
|
||||
dhtopts.Protocols(
|
||||
protocol.ID(prysmProtocolPrefix + "/dht"),
|
||||
),
|
||||
}
|
||||
|
||||
dht, err := kaddht.New(ctx, h, dopts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Wrap host with a routed host so that peers can be looked up in the
|
||||
// distributed hash table by their peer ID.
|
||||
h = rhost.Wrap(h, dht)
|
||||
}
|
||||
s.host = h
|
||||
|
||||
// TODO(3147): Add gossip sub options
|
||||
@@ -95,7 +123,7 @@ func (s *Service) Start() {
|
||||
return
|
||||
}
|
||||
|
||||
if s.cfg.BootstrapNodeAddr != "" && !s.cfg.NoDiscovery {
|
||||
if len(s.cfg.Discv5BootStrapAddr) != 0 && !s.cfg.NoDiscovery {
|
||||
ipAddr := ipAddr(s.cfg)
|
||||
listener, err := startDiscoveryV5(ipAddr, s.privKey, s.cfg)
|
||||
if err != nil {
|
||||
@@ -103,7 +131,7 @@ func (s *Service) Start() {
|
||||
s.startupErr = err
|
||||
return
|
||||
}
|
||||
err = s.addBootNodeToExclusionList()
|
||||
err = s.addBootNodesToExclusionList()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not add bootnode to the exclusion list")
|
||||
s.startupErr = err
|
||||
@@ -112,7 +140,22 @@ func (s *Service) Start() {
|
||||
s.dv5Listener = listener
|
||||
|
||||
go s.listenForNewNodes()
|
||||
go s.maintainBootnode()
|
||||
}
|
||||
|
||||
if len(s.cfg.KademliaBootStrapAddr) != 0 && !s.cfg.NoDiscovery {
|
||||
for _, addr := range s.cfg.KademliaBootStrapAddr {
|
||||
err := startDHTDiscovery(s.host, addr)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not connect to bootnode")
|
||||
s.startupErr = err
|
||||
return
|
||||
}
|
||||
if err := s.addKadDHTNodesToExclusionList(addr); err != nil {
|
||||
s.startupErr = err
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
s.started = true
|
||||
@@ -190,7 +233,7 @@ 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.
|
||||
func (s *Service) listenForNewNodes() {
|
||||
ticker := time.NewTicker(pollingPeriod)
|
||||
bootNode, err := enode.Parse(enode.ValidSchemes, s.cfg.BootstrapNodeAddr)
|
||||
bootNode, err := enode.Parse(enode.ValidSchemes, s.cfg.Discv5BootStrapAddr[0])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -207,28 +250,6 @@ func (s *Service) listenForNewNodes() {
|
||||
}
|
||||
}
|
||||
|
||||
// maintainBootnode connection by infrequently pinging the bootnode ENR. If the bootnode server has
|
||||
// restarted and this client pruned them from the local table, then a ping will reinsert this
|
||||
// clients' ENR into the table of the bootnode again.
|
||||
func (s *Service) maintainBootnode() {
|
||||
if s.cfg.BootstrapNodeAddr == "" {
|
||||
return
|
||||
}
|
||||
ticker := time.NewTicker(bootnodePingPeriod)
|
||||
bootNode := enode.MustParse(s.cfg.BootstrapNodeAddr)
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
log.Debug("Pinging bootnode")
|
||||
if err := s.dv5Listener.Ping(bootNode); err != nil {
|
||||
log.WithError(err).Error("Failed to ping bootnode")
|
||||
}
|
||||
case <-s.ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) connectWithAllPeers(multiAddrs []ma.Multiaddr) {
|
||||
addrInfos, err := peer.AddrInfosFromP2pAddrs(multiAddrs...)
|
||||
if err != nil {
|
||||
@@ -249,22 +270,38 @@ func (s *Service) connectWithAllPeers(multiAddrs []ma.Multiaddr) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) addBootNodeToExclusionList() error {
|
||||
bootNode, err := enode.Parse(enode.ValidSchemes, s.cfg.BootstrapNodeAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
func (s *Service) addBootNodesToExclusionList() error {
|
||||
for _, addr := range s.cfg.Discv5BootStrapAddr {
|
||||
bootNode, err := enode.Parse(enode.ValidSchemes, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
multAddr, err := convertToSingleMultiAddr(bootNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addrInfo, err := peer.AddrInfoFromP2pAddr(multAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// bootnode is never dialled, so ttl is tentatively 1 year
|
||||
s.exclusionList.Set(addrInfo.ID.String(), true, 365*24*time.Hour)
|
||||
}
|
||||
multAddr, err := convertToSingleMultiAddr(bootNode)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) addKadDHTNodesToExclusionList(addr string) error {
|
||||
multiAddr, err := ma.NewMultiaddr(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "could not get multiaddr")
|
||||
}
|
||||
addrInfo, err := peer.AddrInfoFromP2pAddr(multAddr)
|
||||
addrInfo, err := peer.AddrInfoFromP2pAddr(multiAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// bootnode is never dialled, so ttl is tentatively 1 year
|
||||
s.exclusionList.Set(addrInfo.ID.String(), true, 365*24*time.Hour)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -133,8 +133,9 @@ func TestListenForNewNodes(t *testing.T) {
|
||||
bootNode := bootListener.Self()
|
||||
|
||||
cfg = &Config{
|
||||
BootstrapNodeAddr: bootNode.String(),
|
||||
Encoding: "ssz",
|
||||
BootstrapNodeAddr: []string{bootNode.String()},
|
||||
Discv5BootStrapAddr: []string{bootNode.String()},
|
||||
Encoding: "ssz",
|
||||
}
|
||||
var listeners []*discover.UDPv5
|
||||
var hosts []host.Host
|
||||
|
||||
5
proto/beacon/p2p/v1/messages.pb.go
generated
5
proto/beacon/p2p/v1/messages.pb.go
generated
@@ -5,10 +5,11 @@ package ethereum_beacon_p2p_v1
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
5
proto/beacon/p2p/v1/types.pb.go
generated
5
proto/beacon/p2p/v1/types.pb.go
generated
@@ -5,12 +5,13 @@ package ethereum_beacon_p2p_v1
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
github_com_prysmaticlabs_go_bitfield "github.com/prysmaticlabs/go-bitfield"
|
||||
v1alpha1 "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
io "io"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
5
proto/beacon/rpc/v1/services.pb.go
generated
5
proto/beacon/rpc/v1/services.pb.go
generated
@@ -7,14 +7,15 @@ import (
|
||||
context "context"
|
||||
encoding_binary "encoding/binary"
|
||||
fmt "fmt"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
types "github.com/gogo/protobuf/types"
|
||||
_ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
|
||||
v1alpha1 "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
grpc "google.golang.org/grpc"
|
||||
io "io"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
3
proto/beacon/rpc/v1_gateway/services.pb.go
generated
3
proto/beacon/rpc/v1_gateway/services.pb.go
generated
@@ -6,13 +6,14 @@ package ethereum_beacon_rpc_v1
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
math "math"
|
||||
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
empty "github.com/golang/protobuf/ptypes/empty"
|
||||
_ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
|
||||
v1alpha1 "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
grpc "google.golang.org/grpc"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
5
proto/eth/v1alpha1/archive.pb.go
generated
5
proto/eth/v1alpha1/archive.pb.go
generated
@@ -5,10 +5,11 @@ package eth
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
5
proto/eth/v1alpha1/attestation.pb.go
generated
5
proto/eth/v1alpha1/attestation.pb.go
generated
@@ -5,11 +5,12 @@ package eth
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
github_com_prysmaticlabs_go_bitfield "github.com/prysmaticlabs/go-bitfield"
|
||||
io "io"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
5
proto/eth/v1alpha1/beacon_block.pb.go
generated
5
proto/eth/v1alpha1/beacon_block.pb.go
generated
@@ -5,10 +5,11 @@ package eth
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
5
proto/eth/v1alpha1/beacon_chain.pb.go
generated
5
proto/eth/v1alpha1/beacon_chain.pb.go
generated
@@ -6,13 +6,14 @@ package eth
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
types "github.com/gogo/protobuf/types"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
grpc "google.golang.org/grpc"
|
||||
io "io"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
5
proto/eth/v1alpha1/node.pb.go
generated
5
proto/eth/v1alpha1/node.pb.go
generated
@@ -6,12 +6,13 @@ package eth
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
types "github.com/gogo/protobuf/types"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
grpc "google.golang.org/grpc"
|
||||
io "io"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
3
proto/eth/v1alpha1/slasher.pb.go
generated
3
proto/eth/v1alpha1/slasher.pb.go
generated
@@ -6,10 +6,11 @@ package eth
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
math "math"
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
types "github.com/gogo/protobuf/types"
|
||||
grpc "google.golang.org/grpc"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
5
proto/eth/v1alpha1/validator.pb.go
generated
5
proto/eth/v1alpha1/validator.pb.go
generated
@@ -7,13 +7,14 @@ import (
|
||||
context "context"
|
||||
encoding_binary "encoding/binary"
|
||||
fmt "fmt"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
types "github.com/gogo/protobuf/types"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
grpc "google.golang.org/grpc"
|
||||
io "io"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
3
proto/sharding/p2p/v1/messages.pb.go
generated
3
proto/sharding/p2p/v1/messages.pb.go
generated
@@ -5,9 +5,10 @@ package ethereum_sharding_p2p_v1
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
@@ -64,10 +64,9 @@ var (
|
||||
Usage: "Connect with this peer. This flag may be used multiple times.",
|
||||
}
|
||||
// BootstrapNode tells the beacon node which bootstrap node to connect to
|
||||
BootstrapNode = cli.StringFlag{
|
||||
BootstrapNode = cli.StringSliceFlag{
|
||||
Name: "bootstrap-node",
|
||||
Usage: "The address of bootstrap node. Beacon node will connect for peer discovery via DHT",
|
||||
Value: "",
|
||||
}
|
||||
// RelayNode tells the beacon node which relay node to connect to.
|
||||
RelayNode = cli.StringFlag{
|
||||
|
||||
@@ -15,7 +15,15 @@ go_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_ipfs_go_datastore//:go_default_library",
|
||||
"@com_github_ipfs_go_datastore//sync:go_default_library",
|
||||
"@com_github_ipfs_go_log//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//protocol:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_kad_dht//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_kad_dht//opts:go_default_library",
|
||||
"@com_github_multiformats_go_multiaddr//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@org_uber_go_automaxprocs//:go_default_library",
|
||||
@@ -40,7 +48,15 @@ go_image(
|
||||
"@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_ipfs_go_datastore//:go_default_library",
|
||||
"@com_github_ipfs_go_datastore//sync:go_default_library",
|
||||
"@com_github_ipfs_go_log//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//crypto:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_core//protocol:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_kad_dht//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_kad_dht//opts:go_default_library",
|
||||
"@com_github_multiformats_go_multiaddr//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@org_uber_go_automaxprocs//:go_default_library",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
@@ -24,7 +25,15 @@ import (
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
ds "github.com/ipfs/go-datastore"
|
||||
dsync "github.com/ipfs/go-datastore/sync"
|
||||
logging "github.com/ipfs/go-log"
|
||||
libp2p "github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p-core/crypto"
|
||||
"github.com/libp2p/go-libp2p-core/protocol"
|
||||
kaddht "github.com/libp2p/go-libp2p-kad-dht"
|
||||
dhtopts "github.com/libp2p/go-libp2p-kad-dht/opts"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/shared/version"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -32,15 +41,18 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
debug = flag.Bool("debug", false, "Enable debug logging")
|
||||
privateKey = flag.String("private", "", "Private key to use for peer ID")
|
||||
port = flag.Int("port", 4000, "Port to listen for connections")
|
||||
metricsPort = flag.Int("metrics-port", 5000, "Port to listen for connections")
|
||||
externalIP = flag.String("external-ip", "127.0.0.1", "External IP for the bootnode")
|
||||
debug = flag.Bool("debug", false, "Enable debug logging")
|
||||
privateKey = flag.String("private", "", "Private key to use for peer ID")
|
||||
discv5port = flag.Int("discv5-port", 4000, "Port to listen for discv5 connections")
|
||||
kademliaPort = flag.Int("kad-port", 4500, "Port to listen for connections to kad DHT")
|
||||
metricsPort = flag.Int("metrics-port", 5000, "Port to listen for connections")
|
||||
externalIP = flag.String("external-ip", "127.0.0.1", "External IP for the bootnode")
|
||||
|
||||
log = logrus.WithField("prefix", "bootnode")
|
||||
)
|
||||
|
||||
const dhtProtocol = "/prysm/0.0.0/dht"
|
||||
|
||||
type handler struct {
|
||||
listener *discover.UDPv5
|
||||
}
|
||||
@@ -60,14 +72,17 @@ func main() {
|
||||
|
||||
log.Debug("Debug logging enabled.")
|
||||
}
|
||||
privKey, interfacePrivKey := extractPrivateKey()
|
||||
cfg := discover.Config{
|
||||
PrivateKey: extractPrivateKey(),
|
||||
PrivateKey: privKey,
|
||||
}
|
||||
listener := createListener(*externalIP, *port, cfg)
|
||||
listener := createListener(*externalIP, *discv5port, cfg)
|
||||
|
||||
node := listener.Self()
|
||||
log.Infof("Running bootnode: %s", node.String())
|
||||
|
||||
startKademliaDHT(interfacePrivKey)
|
||||
|
||||
handler := &handler{
|
||||
listener: listener,
|
||||
}
|
||||
@@ -81,6 +96,46 @@ func main() {
|
||||
select {}
|
||||
}
|
||||
|
||||
func startKademliaDHT(privKey crypto.PrivKey) {
|
||||
|
||||
if *debug {
|
||||
logging.SetDebugLogging()
|
||||
}
|
||||
|
||||
listen, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d", *externalIP, *kademliaPort))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to construct new multiaddress. %v", err)
|
||||
}
|
||||
opts := []libp2p.Option{
|
||||
libp2p.ListenAddrs(listen),
|
||||
}
|
||||
opts = append(opts, libp2p.Identity(privKey))
|
||||
|
||||
ctx := context.Background()
|
||||
host, err := libp2p.New(ctx, opts...)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create new host. %v", err)
|
||||
}
|
||||
|
||||
dopts := []dhtopts.Option{
|
||||
dhtopts.Datastore(dsync.MutexWrap(ds.NewMapDatastore())),
|
||||
dhtopts.Protocols(
|
||||
protocol.ID(dhtProtocol),
|
||||
),
|
||||
}
|
||||
|
||||
dht, err := kaddht.New(ctx, host, dopts...)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create new dht: %v", err)
|
||||
}
|
||||
if err := dht.Bootstrap(context.Background()); err != nil {
|
||||
log.Fatalf("Failed to bootstrap DHT. %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Running Kademlia DHT bootnode: /ip4/%s/tcp/%d/p2p/%s\n", *externalIP, *kademliaPort, host.ID().Pretty())
|
||||
|
||||
}
|
||||
|
||||
func createListener(ipAddr string, port int, cfg discover.Config) *discover.UDPv5 {
|
||||
ip := net.ParseIP(ipAddr)
|
||||
if ip.To4() == nil {
|
||||
@@ -136,8 +191,9 @@ func createLocalNode(privKey *ecdsa.PrivateKey, ipAddr net.IP, port int) (*enode
|
||||
return localNode, nil
|
||||
}
|
||||
|
||||
func extractPrivateKey() *ecdsa.PrivateKey {
|
||||
func extractPrivateKey() (*ecdsa.PrivateKey, crypto.PrivKey) {
|
||||
var privKey *ecdsa.PrivateKey
|
||||
var interfaceKey crypto.PrivKey
|
||||
if *privateKey != "" {
|
||||
dst, err := hex.DecodeString(*privateKey)
|
||||
if err != nil {
|
||||
@@ -147,6 +203,7 @@ func extractPrivateKey() *ecdsa.PrivateKey {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
interfaceKey = unmarshalledKey
|
||||
privKey = (*ecdsa.PrivateKey)((*btcec.PrivateKey)(unmarshalledKey.(*crypto.Secp256k1PrivateKey)))
|
||||
|
||||
} else {
|
||||
@@ -154,6 +211,7 @@ func extractPrivateKey() *ecdsa.PrivateKey {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
interfaceKey = privInterfaceKey
|
||||
privKey = (*ecdsa.PrivateKey)((*btcec.PrivateKey)(privInterfaceKey.(*crypto.Secp256k1PrivateKey)))
|
||||
log.Warning("No private key was provided. Using default/random private key")
|
||||
b, err := privInterfaceKey.Raw()
|
||||
@@ -163,5 +221,5 @@ func extractPrivateKey() *ecdsa.PrivateKey {
|
||||
log.Debugf("Private key %x", b)
|
||||
}
|
||||
|
||||
return privKey
|
||||
return privKey, interfaceKey
|
||||
}
|
||||
|
||||
@@ -20,13 +20,14 @@ func TestBootnode_OK(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
privKey, _ := extractPrivateKey()
|
||||
cfg := discover.Config{
|
||||
PrivateKey: extractPrivateKey(),
|
||||
PrivateKey: privKey,
|
||||
}
|
||||
listener := createListener(ipAddr, 4000, cfg)
|
||||
defer listener.Close()
|
||||
|
||||
cfg.PrivateKey = extractPrivateKey()
|
||||
cfg.PrivateKey, _ = extractPrivateKey()
|
||||
bootNode, err := enode.Parse(enode.ValidSchemes, listener.Self().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -72,7 +73,7 @@ func TestPrivateKey_ParsesCorrectly(t *testing.T) {
|
||||
}
|
||||
*privateKey = fmt.Sprintf("%x", pk)
|
||||
|
||||
extractedKey := extractPrivateKey()
|
||||
extractedKey, _ := extractPrivateKey()
|
||||
|
||||
rawKey := (*ecdsa.PrivateKey)((*btcec.PrivateKey)(privKey.(*crypto.Secp256k1PrivateKey)))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user