Allow Beacon Node to Connect to Bootstrap Node for Peer Discovery (#740)

* start sequence for node to connect to bootstrap nodes

* lint

* maybe warning is more appropiate?

* fix gazelle

* preston's feedback

* add go-ipfs-addr to workspace

* move flag to shared

* removed routed host
This commit is contained in:
terence tsao
2018-11-14 18:25:06 -08:00
committed by Preston Van Loon
parent 19f6e641e4
commit e1137e5801
15 changed files with 74 additions and 36 deletions

View File

@@ -760,3 +760,9 @@ go_repository(
commit = "20f1fb78b0740ba8c3cb143a61e86ba5c8669768",
importpath = "github.com/hashicorp/golang-lru",
)
go_repository(
name = "com_github_ipfs_go_ipfs_addr",
commit = "489e2d62e87b8986d703b3b28d62a7fcc3978222",
importpath = "github.com/ipfs/go-ipfs-addr",
)

View File

@@ -70,6 +70,7 @@ VERSION:
utils.KeyFlag,
utils.GenesisJSON,
utils.EnablePOWChain,
cmd.BootstrapNode,
cmd.DataDirFlag,
cmd.VerbosityFlag,
cmd.EnableTracingFlag,

View File

@@ -23,7 +23,7 @@ var topicMappings = map[pb.Topic]proto.Message{
}
func configureP2P(ctx *cli.Context) (*p2p.Server, error) {
s, err := p2p.NewServer()
s, err := p2p.NewServer(ctx.GlobalString(cmd.BootstrapNode.Name))
if err != nil {
return nil, err
}

View File

@@ -71,4 +71,9 @@ var (
Name: "keystore-password",
Usage: "Keystore password is used to unlock the keystore so that the users decrypted keys can be used.",
}
// BootstrapNode tells the beacon node which bootstrap node to connect to
BootstrapNode = cli.StringFlag{
Name: "bootstrap-node",
Usage: "The address of bootstrap node. Beacon node will connect for peer discovery via DHT",
}
)

View File

@@ -19,6 +19,7 @@ go_library(
"@com_github_golang_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_libp2p_go_libp2p//:go_default_library",
"@com_github_libp2p_go_libp2p//p2p/discovery:go_default_library",
"@com_github_libp2p_go_libp2p//p2p/host/routed:go_default_library",

View File

@@ -4,7 +4,8 @@ import (
"context"
"time"
host "github.com/libp2p/go-libp2p-host"
iaddr "github.com/ipfs/go-ipfs-addr"
"github.com/libp2p/go-libp2p-host"
ps "github.com/libp2p/go-libp2p-peerstore"
mdns "github.com/libp2p/go-libp2p/p2p/discovery"
"github.com/sirupsen/logrus"
@@ -18,11 +19,9 @@ var discoveryInterval = 1 * time.Minute
// mDNSTag is the name of the mDNS service.
var mDNSTag = mdns.ServiceTag
// startDiscovery protocols. Currently, this supports discovery via multicast
// DNS peer discovery.
//
// TODO(287): add other discovery protocols such as DHT, etc.
func startDiscovery(ctx context.Context, host host.Host) error {
// startmDNSDiscovery supports discovery via multicast DNS peer discovery.
func startmDNSDiscovery(ctx context.Context, host host.Host) error {
mdnsService, err := mdns.NewMdnsService(ctx, host, discoveryInterval, mDNSTag)
if err != nil {
return err
@@ -32,6 +31,21 @@ func startDiscovery(ctx context.Context, host host.Host) error {
return nil
}
// startDHTDiscovery supports discovery via DHT.
func startDHTDiscovery(ctx context.Context, host host.Host, bootstrapAddr string) error {
addr, err := iaddr.ParseString(bootstrapAddr)
if err != nil {
return err
}
peerinfo, err := ps.InfoFromP2pAddr(addr.Multiaddr())
if err != nil {
return err
}
err = host.Connect(ctx, *peerinfo)
return err
}
// Discovery implements mDNS notifee interface.
type discovery struct {
ctx context.Context

View File

@@ -31,13 +31,13 @@ func TestStartDiscovery_HandlePeerFound(t *testing.T) {
defer cancel()
a := bhost.New(swarmt.GenSwarm(t, ctx))
err := startDiscovery(ctx, a)
err := startmDNSDiscovery(ctx, a)
if err != nil {
t.Errorf("Error when starting discovery: %v", err)
}
b := bhost.New(swarmt.GenSwarm(t, ctx))
err = startDiscovery(ctx, b)
err = startmDNSDiscovery(ctx, b)
if err != nil {
t.Errorf("Error when starting discovery: %v", err)
}

View File

@@ -8,7 +8,7 @@ import (
// Feeds can be use to subscribe to any type of message.
func ExampleServer_Feed() {
s, err := NewServer()
s, err := NewServer("")
if err != nil {
panic(err)
}

View File

@@ -23,7 +23,7 @@ func TestFeed_ReturnsSameFeed(t *testing.T) {
{a: &testpb.Puzzle{}, b: &testpb.TestMessage{}, want: false},
}
s, _ := NewServer()
s, _ := NewServer("")
for _, tt := range tests {
feed1 := s.Feed(tt.a)

View File

@@ -31,7 +31,7 @@ func adapterWithParams(i int) p2p.Adapter {
func ExampleServer_RegisterTopic() {
adapters := []p2p.Adapter{reqLogger, adapterWithParams(5)}
s, _ := p2p.NewServer()
s, _ := p2p.NewServer("")
var topic string
var message proto.Message

View File

@@ -26,17 +26,18 @@ type Sender interface {
// Server is a placeholder for a p2p service. To be designed.
type Server struct {
ctx context.Context
cancel context.CancelFunc
mutex *sync.Mutex
feeds map[reflect.Type]Feed
host host.Host
gsub *pubsub.PubSub
topicMapping map[reflect.Type]string
ctx context.Context
cancel context.CancelFunc
mutex *sync.Mutex
feeds map[reflect.Type]Feed
host host.Host
gsub *pubsub.PubSub
topicMapping map[reflect.Type]string
bootstrapNode string
}
// NewServer creates a new p2p server instance.
func NewServer() (*Server, error) {
func NewServer(bootstrapNode string) (*Server, error) {
ctx, cancel := context.WithCancel(context.Background())
opts := buildOptions()
h, err := libp2p.New(ctx, opts...)
@@ -57,21 +58,29 @@ func NewServer() (*Server, error) {
}
return &Server{
ctx: ctx,
cancel: cancel,
feeds: make(map[reflect.Type]Feed),
host: h,
gsub: gsub,
mutex: &sync.Mutex{},
topicMapping: make(map[reflect.Type]string),
ctx: ctx,
cancel: cancel,
feeds: make(map[reflect.Type]Feed),
host: h,
gsub: gsub,
mutex: &sync.Mutex{},
topicMapping: make(map[reflect.Type]string),
bootstrapNode: bootstrapNode,
}, nil
}
// Start the main routine for an p2p server.
func (s *Server) Start() {
log.Info("Starting service")
if err := startDiscovery(s.ctx, s.host); err != nil {
log.Errorf("Could not start p2p discovery! %v", err)
if s.bootstrapNode != "" {
if err := startDHTDiscovery(s.ctx, s.host, s.bootstrapNode); err != nil {
log.Errorf("Could not start peer discovery via DHT: %v", err)
}
}
if err := startmDNSDiscovery(s.ctx, s.host); err != nil {
log.Errorf("Could not start peer discovery via mDNS: %v", err)
return
}
}

View File

@@ -9,7 +9,7 @@ import (
func TestLifecycle(t *testing.T) {
hook := logTest.NewGlobal()
s, err := NewServer()
s, err := NewServer("")
if err != nil {
t.Fatalf("Could not start a new server: %v", err)
}

View File

@@ -37,7 +37,7 @@ func init() {
}
func TestBroadcast(t *testing.T) {
s, err := NewServer()
s, err := NewServer("")
if err != nil {
t.Fatalf("Could not start a new server: %v", err)
}
@@ -49,7 +49,7 @@ func TestBroadcast(t *testing.T) {
}
func TestEmitFailsNonProtobuf(t *testing.T) {
s, _ := NewServer()
s, _ := NewServer("")
hook := logTest.NewGlobal()
s.emit(Message{}, &event.Feed{}, nil /*msg*/, reflect.TypeOf(""))
want := "Received message is not a protobuf message: string"
@@ -59,7 +59,7 @@ func TestEmitFailsNonProtobuf(t *testing.T) {
}
func TestEmitFailsUnmarshal(t *testing.T) {
s, _ := NewServer()
s, _ := NewServer("")
hook := logTest.NewGlobal()
msg := &pubsub.Message{
&pubsubPb.Message{
@@ -75,7 +75,7 @@ func TestEmitFailsUnmarshal(t *testing.T) {
}
func TestEmit(t *testing.T) {
s, _ := NewServer()
s, _ := NewServer("")
p := &testpb.TestMessage{Foo: "bar"}
d, err := proto.Marshal(p)
if err != nil {
@@ -199,7 +199,7 @@ func testSubscribe(ctx context.Context, t *testing.T, s Server, gsub *pubsub.Pub
func TestRegisterTopic_WithoutAdapters(t *testing.T) {
// TODO(488): Unskip this test
t.Skip("Currently failing to simulate incoming p2p messages. See github.com/prysmaticlabs/prysm/issues/488")
s, err := NewServer()
s, err := NewServer("")
if err != nil {
t.Fatalf("Failed to create new server: %v", err)
}
@@ -240,7 +240,7 @@ func TestRegisterTopic_WithoutAdapters(t *testing.T) {
func TestRegisterTopic_WithAdapters(t *testing.T) {
// TODO(488): Unskip this test
t.Skip("Currently failing to simulate incoming p2p messages. See github.com/prysmaticlabs/prysm/issues/488")
s, err := NewServer()
s, err := NewServer("")
if err != nil {
t.Fatalf("Failed to create new server: %v", err)
}

View File

@@ -64,6 +64,7 @@ VERSION:
app.Flags = []cli.Flag{
types.BeaconRPCProviderFlag,
types.PubKeyFlag,
types.BeaconRPCProviderFlag,
cmd.VerbosityFlag,
cmd.DataDirFlag,
cmd.EnableTracingFlag,
@@ -71,6 +72,7 @@ VERSION:
cmd.TraceSampleFractionFlag,
cmd.KeystorePasswordFlag,
cmd.KeystoreDirectoryFlag,
cmd.BootstrapNode,
debug.PProfFlag,
debug.PProfAddrFlag,
debug.PProfPortFlag,

View File

@@ -16,7 +16,7 @@ var topicMappings = map[pb.Topic]proto.Message{
}
func configureP2P(ctx *cli.Context) (*p2p.Server, error) {
s, err := p2p.NewServer()
s, err := p2p.NewServer(ctx.GlobalString(cmd.BootstrapNode.Name))
if err != nil {
return nil, err
}