p2p

package
v0.0.0-...-c85edb6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 9, 2019 License: GPL-3.0 Imports: 25 Imported by: 0

Documentation

Overview

Package p2p handles peer-to-peer networking for Ethereum Serenity clients.

There are three types of p2p communications.

  • Direct: two peer communication
  • Floodsub: peer broadcasting to all peers
  • Gossipsub: peer broadcasting to localized peers

This communication is abstracted through the Feed, Broadcast, and Send.

Pub/sub topic has a specific message type that is used for that topic.

Read more about gossipsub at https://github.com/vyzo/gerbil-simsub

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func MakePeer

func MakePeer(addr string) (*peerstore.PeerInfo, error)

MakePeer from multiaddress string.

Types

type Adapter

type Adapter func(Handler) Handler

Adapter is used to create middleware.

See http://godoc.org/github.com/prysmaticlabs/prysm/shared/p2p#Server.RegisterTopic

type Broadcaster

type Broadcaster interface {
	Broadcast(proto.Message)
}

Broadcaster represents a subset of the p2p.Server. This interface is useful for testing or when the calling code only needs access to the broadcast method.

type Feed

type Feed interface {
	Subscribe(channel interface{}) event.Subscription
	Send(value interface{}) (nsent int)
}

Feed implements one-to-many subscriptions where the carrier of events is a channel. Values sent to a Feed are delivered to all subscribed channels simultaneously.

Feeds can only be used with a single type. The type is determined by the first Send or Subscribe operation. Subsequent calls to these methods panic if the type does not match.

Implemented by https://github.com/ethereum/go-ethereum/blob/HEAD/event/feed.go

type Handler

type Handler func(Message)

Handler is a callback used in the adapter/middleware stack chain.

See http://godoc.org/github.com/prysmaticlabs/prysm/shared/p2p#Server.RegisterTopic

type Message

type Message struct {
	// Ctx message context.
	Ctx context.Context
	// Peer represents the sender of the message.
	Peer Peer
	// Data can be any type of message found in sharding/p2p/proto package.
	Data proto.Message
}

Message represents a message received from an external peer.

type Sender

type Sender interface {
	Send(msg interface{}, peer Peer)
}

Sender represents a struct that is able to relay information via p2p. Server implements this interface.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is a placeholder for a p2p service. To be designed.

func NewServer

func NewServer(cfg *ServerConfig) (*Server, error)

NewServer creates a new p2p server instance.

func (*Server) Broadcast

func (s *Server) Broadcast(msg proto.Message)

Broadcast publishes a message to all localized peers using gossipsub. msg must be a proto.Message that can be encoded into a byte array. It publishes the first 100 chars of msg over the msg's mapped topic. To map a messageType to a topic, use RegisterTopic.

It logs an error if msg is not a protobuf message, if msg cannot be encoded into a byte array, or if the server is unable to publish the message over gossipsub.

msg := make(chan p2p.Message, 100) // Choose a reasonable buffer size!
ps.RegisterTopic("message_topic_here", msg)
ps.Broadcast(msg)

func (*Server) Feed

func (s *Server) Feed(msg proto.Message) Feed

Feed is a one to many subscription feed of the argument type.

Messages received via p2p protocol are sent to subscribers by these event feeds. Message consumers should not use event feeds to reply to or broadcast messages. The p2p server will not relay them to peers. Rather, use the Send() or Broadcast() method on p2p.Server.

Event feeds from p2p will always be of type p2p.Message. The message contains information about the sender, aka the peer, and the message payload itself.

feed, err := ps.Feed(&pb.MyMessage{})
ch := make(chan p2p.Message, 100) // Choose a reasonable buffer size!
sub := feed.Subscribe(ch)

// Wait until my message comes from a peer.
msg := <- ch
fmt.Printf("Message received: %v", msg.Data)
Example

Feeds can be use to subscribe to any type of message.

s, err := NewServer(&ServerConfig{})
if err != nil {
	panic(err)
}

// Let's wait for a puzzle from our peers then try to solve it.
feed := s.Feed(&pb.Puzzle{})

ch := make(chan Message, 5) // Small buffer size. I don't expect many puzzles.
sub := feed.Subscribe(ch)

// Always close these resources.
defer sub.Unsubscribe()
defer close(ch)

// Wait until we have a puzzle to solve.
msg := <-ch
puzzle, ok := msg.Data.(*pb.Puzzle)

if !ok {
	panic("Received a message that wasn't a puzzle!")
}

fmt.Printf("Received puzzle %s from peer %v\n", puzzle, msg.Peer)

if puzzle.Answer == "fourteen" {
	fmt.Println("I solved the puzzle!")
} else {
	fmt.Println("The answer isn't \"fourteen\"... giving up")
}
Output:

func (*Server) RegisterTopic

func (s *Server) RegisterTopic(topic string, message proto.Message, adapters ...Adapter)

RegisterTopic with a message and the adapter stack for the given topic. The message type provided will be feed selector for emitting messages received on a given topic.

The topics can originate from multiple sources. In other words, messages on TopicA may come from direct peer communication or a pub/sub channel.

Example
package main

import (
	"fmt"

	"github.com/gogo/protobuf/proto"
	"github.com/prysmaticlabs/prysm/shared/p2p"
)

// A basic adapter will complete its logic then call next. Some adapters
// may choose not to call next. For example, in the case of a rate
// limiter or blacklisting condition.
func reqLogger(next p2p.Handler) p2p.Handler {
	return func(msg p2p.Message) {
		fmt.Printf("Received message from %v\n", msg.Peer)
		next(msg)
	}
}

// Functions can return an adapter in order to capture configuration.
func adapterWithParams(i int) p2p.Adapter {
	return func(next p2p.Handler) p2p.Handler {
		return func(msg p2p.Message) {
			fmt.Printf("Magic number is %d\n", i)
			i++
			next(msg)
		}
	}
}

func main() {
	adapters := []p2p.Adapter{reqLogger, adapterWithParams(5)}

	s, _ := p2p.NewServer(&p2p.ServerConfig{})

	var topic string
	var message proto.Message

	s.RegisterTopic(topic, message, adapters...)

	ch := make(chan p2p.Message)
	sub := s.Subscribe(message, ch)
	defer sub.Unsubscribe()
}
Output:

func (*Server) Send

func (s *Server) Send(msg proto.Message, peer Peer)

Send a message to a specific peer.

func (*Server) Start

func (s *Server) Start()

Start the main routine for an p2p server.

func (*Server) Status

func (s *Server) Status() error

Status returns an error if the p2p service does not have sufficient peers.

func (*Server) Stop

func (s *Server) Stop() error

Stop the main p2p loop.

func (*Server) Subscribe

func (s *Server) Subscribe(msg proto.Message, channel chan Message) event.Subscription

Subscribe returns a subscription to a feed of msg's Type and adds the channels to the feed.

type ServerConfig

type ServerConfig struct {
	BootstrapNodeAddr string
	RelayNodeAddr     string
	Port              int
}

ServerConfig for peer to peer networking.

Directories

Path Synopsis
adapter
metric
Package metric contain some prometheus collectors for p2p services.
Package metric contain some prometheus collectors for p2p services.
Package mock_p2p is a generated GoMock package.
Package mock_p2p is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL