2019-08-13 21:12:00 +00:00
|
|
|
package p2p
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/libp2p/go-libp2p"
|
|
|
|
"github.com/libp2p/go-libp2p-core/host"
|
2019-08-16 17:13:04 +00:00
|
|
|
network "github.com/libp2p/go-libp2p-core/network"
|
2019-08-16 20:03:11 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
2019-08-16 17:13:04 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/protocol"
|
2019-08-13 21:12:00 +00:00
|
|
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
|
|
"github.com/pkg/errors"
|
2019-08-16 17:13:04 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/encoder"
|
2019-08-13 21:12:00 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ = shared.Service(&Service{})
|
|
|
|
|
|
|
|
// Service for managing peer to peer (p2p) networking.
|
|
|
|
type Service struct {
|
|
|
|
ctx context.Context
|
|
|
|
cancel context.CancelFunc
|
|
|
|
|
|
|
|
started bool
|
|
|
|
cfg *Config
|
|
|
|
startupErr error
|
|
|
|
|
|
|
|
host host.Host
|
|
|
|
pubsub *pubsub.PubSub
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewService initializes a new p2p service compatible with shared.Service interface. No
|
|
|
|
// connections are made until the Start function is called during the service registry startup.
|
|
|
|
func NewService(cfg *Config) (*Service, error) {
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
return &Service{
|
|
|
|
ctx: ctx,
|
|
|
|
cancel: cancel,
|
|
|
|
cfg: cfg,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start the p2p service.
|
|
|
|
func (s *Service) Start() {
|
|
|
|
if s.started {
|
|
|
|
log.Error("Attempted to start p2p service when it was already started")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
s.started = true
|
|
|
|
|
|
|
|
// TODO(3147): Add host options
|
|
|
|
h, err := libp2p.New(s.ctx)
|
|
|
|
if err != nil {
|
|
|
|
s.startupErr = err
|
|
|
|
return
|
|
|
|
}
|
|
|
|
s.host = h
|
|
|
|
|
|
|
|
// TODO(3147): Add gossip sub options
|
|
|
|
gs, err := pubsub.NewGossipSub(s.ctx, s.host)
|
|
|
|
if err != nil {
|
|
|
|
s.startupErr = err
|
|
|
|
return
|
|
|
|
}
|
|
|
|
s.pubsub = gs
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop the p2p service and terminate all peer connections.
|
|
|
|
func (s *Service) Stop() error {
|
|
|
|
s.started = false
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Status of the p2p service. Will return an error if the service is considered unhealthy to
|
|
|
|
// indicate that this node should not serve traffic until the issue has been resolved.
|
|
|
|
func (s *Service) Status() error {
|
|
|
|
if !s.started {
|
|
|
|
return errors.New("not running")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2019-08-16 17:13:04 +00:00
|
|
|
|
|
|
|
// Encoding returns the configured networking encoding.
|
|
|
|
func (s *Service) Encoding() encoder.NetworkEncoding {
|
2019-08-18 04:32:39 +00:00
|
|
|
// TODO(3147): Return based on flag value
|
|
|
|
return &encoder.SszNetworkEncoder{}
|
2019-08-16 17:13:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PubSub returns the p2p pubsub framework.
|
|
|
|
func (s *Service) PubSub() *pubsub.PubSub {
|
|
|
|
return s.pubsub
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetStreamHandler sets the protocol handler on the p2p host multiplexer.
|
|
|
|
// This method is a pass through to libp2pcore.Host.SetStreamHandler.
|
|
|
|
func (s *Service) SetStreamHandler(topic string, handler network.StreamHandler) {
|
|
|
|
s.host.SetStreamHandler(protocol.ID(topic), handler)
|
|
|
|
}
|
2019-08-16 20:03:11 +00:00
|
|
|
|
|
|
|
// Disconnect from a peer.
|
|
|
|
func (s *Service) Disconnect(pid peer.ID) error {
|
|
|
|
// TODO(3147): Implement disconnect
|
|
|
|
return nil
|
|
|
|
}
|