p2p

package
v6.5.0-p2p2-beta0+inco... Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2019 License: Apache-2.0, BSD-2-Clause, BSD-3-Clause, + 4 more Imports: 19 Imported by: 0

README

Standalone Implementation of Factom's P2P Network

Summary

This package implements a partial gossip network, limited to peer connectivity and delivery of messages. The application is responsible for triggering fanout, rounds, and message repetition detection.

This is a complete rework of the code that aims to get rid of uncertainty of connections as well as polling strategies and also add support for handling multiple protocol versions. This will open up opportunities to improve network flow through generational increments without breaking backward compatibility.

Goals:

  • Fully configurable, independent, isolated instances
  • Add handshake process to connections to distinguish and identify nodes
  • Ability to handle multiple protocol schemes starting from version 9
  • Reduced network packet overhead in scheme version 10
  • Simple integration
  • Easier to read code with comprehensive documentation

Motivation

  • Peers are not identifiable beyond ip address. Multiple connections from the same node are not differentiated and assigned random numbers
  • Peers have inconsistent information (some data is only available after the first transmission)
  • Nodes depend on the seed file to join the network even across reboots; peers are not persisted
  • Connections are polled in a single loop to check for new data causing unnecessary delays
  • Connections have a complicated state machine and correlation with a Peer object
  • Complicated program flow with a lot of mixed channels, some of which are polled

Tackling some of these would require significant overhaul of the existing code to the point where it seemed like it would be easier to start from scratch.

Specification

Terminology

  • Peer/Node: A node is any application that uses the same p2p protocol to connect to the network. A peer is a node that is connected to us.
  • Endpoint: An internet location a node can connect to. Consists of an IP address and port.
  • Peer Hash: Each peer receives a unique peer hash using the format [ip]:[port] [hex nodeid], where [ip] is taken from the TCP connection itself, and [port] and [hex nodeid] are determined from the peer's handshake.
  • Parcel: A parcel is a container for network messages that has a type and a payload. Parcels of the application type are delivered to the application, others are used internally.

Protocol

CAT Peering

The CAT (Cyclic Auto Truncate) is a cyclic peering strategy to prevent a rigid network structure. It's based on rounds, during which random peers are indiscriminately dropped to make room for new connections. If a node is full it will reject incoming connections and provide a list of alternative nodes to try and peer with. There are three components, Rounds, Replenish, and Listen.

Round

Rounds run once every 15 minutes (config: RoundTime). It gets a list of peers and if there are more than 30 peers (config: Drop), it randomly selects non-special peers to drop to reach 30 peers.

Replenish

The goal of Replenish is to reach 32 (config: Target) active connections. If there are 32 or more connections, Replenish waits. Otherwise, it runs once a second.

The first step is to pick a list of peers to connect to: If there are fewer than 10 (config: MinReseed) connections, replenish retrieves the peers from the seed file to connect to. Otherwise, it sends a Peer-Request message to a random peer in the connection pool. If it receives a response within 5 seconds, it will select one random peer from the provided list.

The second step is to dial the peers in the list. If a peer in the list rejects the connection with alternatives, the alternatives are added to the list. It dials to the list sequentially until either 32 connections are reached, the list is empty, or 4 connection attempts (working or failed) have been made.

Listen

When a new TCP connection arrives, the node checks if the IP is banned, if there are more than 36 (config: Incoming) connections, or (if conf.PeerIPLimitIncoming > 0) there are more than conf.PeerIPLimitIncoming connections from that specific IP. If any of those are true, the connection is rejected. Otherwise, it continues with a Handshake.

Peers that are rejected are given a list of 3 (conf: PeerShareAmount) random peers the node is connected to in a Reject-Alternative message.

Handshake

The handshake starts with an already established TCP connection.

  1. A deadline of 10 seconds (conf: HandshakeTimeout) is set for both reading and writing
  2. Generate a Handshake containing our preferred version (conf: ProtocolVersion), listen port (conf: ListenPort), network id (conf: Network), and node id (conf: NodeID) and send it across the wire
  3. Blocking read the first message
  4. Verify that we are in the same network
  5. Calculate the minimum of both our and their version
  6. Check if we can handle that version (conf: ProtocolVersionMinimum) and initialize the protocol adapter
  7. If it's an outgoing connection, check if the Handshake is of type RejectAlternative, in which case we parse the list of alternate endpoints

If any step fails, the handshake will fail.

For backward compatibility, the Handshake message is in the same format as protocol v9 requests but it uses the type "Handshake". Nodes running the old software will just drop the invalid message without affecting the node's status in any way.

9

Protocol 9 is the legacy (Factomd v6.4 and lower) protocol with the ability to split messages into parts disabled. V9 has the disadvantage of sending unwanted overhead with every message, namely Network, Version, Length, Address, Part info, NodeID, Address, Port. In the old p2p system this was used to post-load information but now has been shifted to the handshake.

Data is serialized via Golang's gob.

10

Protocol 10 is the slimmed down version of V9, containing only the Type, CRC32 of the payload, and the payload itself. Data is also serialized via Golang's gob.

Documentation

Index

Constants

View Source
const (
	// Broadcast sends a parcel to multiple peers (randomly selected based on fanout and special peers)
	Broadcast = "<BROADCAST>"
	// FullBroadcast sends a parcel to all peers
	FullBroadcast = "<FULLBORADCAST>"
	// RandomPeer sends a parcel to one randomly selected peer
	RandomPeer = "<RANDOMPEER>"
)

Variables

This section is empty.

Functions

func DebugServer

func DebugServer(n *Network)

DebugServer is temporary

func IP2Location

func IP2Location(addr string) (uint32, error)

IP2Location converts an ip address to a uint32

If the address is a hostmask, it attempts to resolve the address first

func IP2LocationQuick

func IP2LocationQuick(addr string) uint32

IP2LocationQuick converts an ip address to a uint32 without a hostmask lookup

func StringToUint32

func StringToUint32(input string) uint32

StringToUint32 hashes the input to generate a deterministic number representation

func WebScanner

func WebScanner(url string, f func(line string)) error

WebScanner is a wrapper that applies the closure f to the response body

Types

type Configuration

type Configuration struct {
	// Network is the NetworkID of the network to use, eg. MainNet, TestNet, etc
	Network NetworkID

	// NodeID is this node's id
	NodeID uint32
	// NodeName is the internal name of the node
	NodeName string

	// === Peer Management Settings ===
	// PeerRequestInterval dictates how often neighbors should be asked for an
	// updated peer list
	PeerRequestInterval time.Duration
	// PeerReseedInterval dictates how often the seed file should be accessed
	// to check for changes
	PeerReseedInterval time.Duration
	// PeerIPLimit specifies the maximum amount of peers to accept from a single
	// ip address
	// 0 for unlimited
	PeerIPLimitIncoming uint
	PeerIPLimitOutgoing uint

	// Special is a list of special peers, separated by comma. If no port is specified, the entire
	// ip is considered special
	Special string

	// PersistFile is the filepath to the file to save peers
	PersistFile string
	// how often to save these
	PersistInterval time.Duration

	// to count as being connected
	// PeerShareAmount is the number of peers we share
	PeerShareAmount uint

	// CAT Settings
	RoundTime time.Duration
	Target    uint
	Max       uint
	Drop      uint
	MinReseed uint
	Incoming  uint // maximum inbound connections, 0 <= Incoming <= Max

	// Fanout controls how many random peers are selected for propagating messages
	// Higher values increase fault tolerance but also increase network congestion
	Fanout uint

	// SeedURL is the URL of the remote seed file
	SeedURL string // URL to a source of peer info

	// BindIP is the ip address to bind to for listening and connecting
	//
	// leave blank to bind to all
	BindIP string
	// ListenPort is the port to listen to incoming tcp connections on
	ListenPort string
	// ListenLimit is the lockout period of accepting connections from a single
	// ip after having a successful connection from that ip
	ListenLimit time.Duration

	// PingInterval dictates the maximum amount of time a connection can be
	// silent (no writes) before sending a Ping
	PingInterval time.Duration

	// RedialInterval dictates how long to wait between connection attempts
	RedialInterval time.Duration

	// ManualBan is the duration to ban an address for when banned manually
	ManualBan time.Duration

	// HandshakeDeadline is the maximum acceptable time for an incoming conneciton
	// to send the first parcel after connecting
	HandshakeTimeout time.Duration
	DialTimeout      time.Duration

	// ReadDeadline is the maximum acceptable time to read a single parcel
	// if a connection takes longer, it is disconnected
	ReadDeadline time.Duration

	// WriteDeadline is the maximum acceptable time to send a single parcel
	// if a connection takes longer, it is disconnected
	WriteDeadline time.Duration

	ProtocolVersion uint16
	// ProtocolVersionMinimum is the earliest version this package supports
	ProtocolVersionMinimum uint16

	ChannelCapacity uint

	EnablePrometheus bool // Enable prometheus logging. Disable if you run multiple instances
}

Configuration defines the behavior of the gossip network protocol

func DefaultP2PConfiguration

func DefaultP2PConfiguration() (c Configuration)

DefaultP2PConfiguration returns a network configuration with base values These should be overwritten with command line and config parameters

func (*Configuration) Sanitize

func (c *Configuration) Sanitize()

type Dialer

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

Dialer is a construct to throttle dialing and limit by attempts

func NewDialer

func NewDialer(bindTo string, interval, timeout time.Duration) (*Dialer, error)

NewDialer creates a new Dialer

func (*Dialer) Bind

func (d *Dialer) Bind(to string) error

func (*Dialer) CanDial

func (d *Dialer) CanDial(ep Endpoint) bool

CanDial checks if the given ip can be dialed yet

func (*Dialer) Dial

func (d *Dialer) Dial(ep Endpoint) (net.Conn, error)

Dial an ip. Returns the active TCP connection or error if it failed to connect

type Endpoint

type Endpoint struct {
	IP   string `json:"ip"`
	Port string `json:"port"`
}

func NewEndpoint

func NewEndpoint(ip, port string) (Endpoint, error)

NewEndpoint creates an Endpoint struct from a given ip and port, throws error if ip could not be resolved

func ParseEndpoint

func ParseEndpoint(s string) (Endpoint, error)

ParseEndpoint takes input in the form of "ip:port" and returns its IP

func (Endpoint) String

func (ep Endpoint) String() string

func (Endpoint) Valid

func (ep Endpoint) Valid() bool

Verify checks if the data is usable. Does not check if the remote address works

type Handshake

type Handshake V9Msg

Handshake is an alias of V9MSG for backward compatibility

func (*Handshake) SetPayload

func (h *Handshake) SetPayload(payload []byte)

SetPayload adds a payload to the handshake and updates the header with metadata

func (*Handshake) Valid

func (h *Handshake) Valid(conf *Configuration) error

Valid checks if the other node is compatible

type Info

type Info struct {
	Peers     int     // number of peers connected
	Receiving float64 // download rate in Messages/s
	Sending   float64 // upload rate in Messages/s
	Download  float64 // download rate in Bytes/s
	Upload    float64 // upload rate in Bytes/s
	Dropped   uint64  // number of parcels dropped due to low speed
}

Info holds the data that can be queried from the Network

type LimitedListener

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

LimitedListener will block multiple connection attempts from a single ip within a specific timeframe

func NewLimitedListener

func NewLimitedListener(address string, limit time.Duration) (*LimitedListener, error)

NewLimitedListener initializes a new listener for the specified address (address:port) throttling incoming connections

func (*LimitedListener) Accept

func (ll *LimitedListener) Accept() (net.Conn, error)

Accept accepts a connection if no other connection attempt from that ip has been made in the specified time frame

func (*LimitedListener) Addr

func (ll *LimitedListener) Addr() net.Addr

Addr returns the address the listener is listening to

func (*LimitedListener) Close

func (ll *LimitedListener) Close()

Close closes the associated net.Listener

type Measure

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

Measure measures the per-second rates of messages and bandwidth based on individual calls

func NewMeasure

func NewMeasure(rate time.Duration) *Measure

NewMeasure initializes a new measuring tool based on the given rate Rate must be at least one second and should be multiples of seconds

func (*Measure) GetRate

func (m *Measure) GetRate() (float64, float64, float64, float64)

GetRate returns the current rates measured this interval (Parcels Received, Parcels Sent, Bytes Received, Bytes Sent)

func (*Measure) Receive

func (m *Measure) Receive(size uint64)

Receive signals that we received a parcel of the given size

func (*Measure) Send

func (m *Measure) Send(size uint64)

Send signals that we sent a parcel of the given size

type MetricsReadWriter

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

MetricsReadWriter is a wrapper for net.Conn that allows the package to observe the actual amount of bytes passing through it

func NewMetricsReadWriter

func NewMetricsReadWriter(rw io.ReadWriter) *MetricsReadWriter

func (*MetricsReadWriter) Collect

func (sc *MetricsReadWriter) Collect() (mw uint64, mr uint64, bw uint64, br uint64)

func (*MetricsReadWriter) Read

func (sc *MetricsReadWriter) Read(p []byte) (int, error)

func (*MetricsReadWriter) Write

func (sc *MetricsReadWriter) Write(p []byte) (int, error)

type Network

type Network struct {
	ToNetwork   ParcelChannel
	FromNetwork ParcelChannel
	// contains filtered or unexported fields
}

Network is the main access point for outside applications.

ToNetwork is the channel over which to send parcels to the network layer

FromNetwork is the channel that gets filled with parcels arriving from the network layer

func NewNetwork

func NewNetwork(conf Configuration) (*Network, error)

NewNetwork initializes a new network with the given configuration. The passed Configuration is copied and cannot be modified afterwards. Does not start the network automatically.

func (*Network) AddSpecial

func (n *Network) AddSpecial(raw string)

AddSpecial takes a set of ip addresses that should be treated as special. Network will always attempt to have a connection to a special peer. Format is a single line of ip addresses and ports, separated by semicolon, eg "127.0.0.1:8088;8.8.8.8;192.168.0.1:8110"

The port is optional and the entire ip will be considered special if no port is provided

func (*Network) Ban

func (n *Network) Ban(hash string)

Ban removes a peer as well as any other peer from that address and prevents any connection being established for the amount of time set in the configuration (default one week)

func (*Network) DebugMessage

func (n *Network) DebugMessage() (string, string, int)

DebugMessage is temporary

func (*Network) Disconnect

func (n *Network) Disconnect(hash string)

Disconnect severs connection for a specific peer. They are free to connect again afterward

func (*Network) GetInfo

func (n *Network) GetInfo() Info

func (*Network) GetPeerMetrics

func (n *Network) GetPeerMetrics() map[string]PeerMetrics

func (*Network) Rounds

func (n *Network) Rounds() int

Rounds returns the total number of CAT rounds that have occurred

func (*Network) Run

func (n *Network) Run()

Run starts the network. Listens to incoming connections on the specified port and connects to other peers

func (*Network) SetMetricsHook

func (n *Network) SetMetricsHook(f func(pm map[string]PeerMetrics))

SetMetricsHook allows you to read peer metrics. Gets called approximately once a second and transfers the metrics of all CONNECTED peers in the format "identifying hash" -> p2p.PeerMetrics

func (*Network) Stop

func (n *Network) Stop()

func (*Network) Total

func (n *Network) Total() int

Total returns the number of active connections

type NetworkID

type NetworkID uint32

NetworkID represents the P2P network we are participating in (eg: test, nmain, etc.)

const (
	MainNet  NetworkID = 0xfeedbeef
	TestNet  NetworkID = 0xdeadbeef
	LocalNet NetworkID = 0xbeaded
)

NetworkID are specific uint32s to identify separate networks

The default identifiers are MainNet (the main production network), TestNet (for network=TESTNET) and LocalNet (for network=LOCAL).

Custom NetworkIDs (network=CUSTOM) are generated from the "customnet" command line flag

func NewNetworkID

func NewNetworkID(name string) NetworkID

NewNetworkID converts a string to a network id

func (*NetworkID) String

func (n *NetworkID) String() string

type Parcel

type Parcel struct {
	Type    ParcelType // 2 bytes - network level commands (eg: ping/pong)
	Address string     // ? bytes - "" or nil for broadcast, otherwise the destination peer's hash.
	Payload []byte
}

Parcel is the raw data interface between the network, the p2p package, and the application.

Type indicates the network or application type. Messages routed to and from the application will only have application types

Address is a unique internal identifier for origin or target of the parcel. For messages from the network to the application, the address will the id of the sender. Messages intended to be returned to the sender should bear the same address.

There are three special address constants:

Broadcast: The message will be sent to multiple peers as specified by the fanout
FullBroadcast: The message will be sent to all peers
RandomPeer: The message will be sent to one peer picked at random

The payload is arbitrary data defined at application level

func NewParcel

func NewParcel(target string, payload []byte) *Parcel

NewParcel creates a new application message. The target should be either an identifier from a previous message, or one of the custom flags: Broadcast, BroadcastFull, RandomPeer

func (*Parcel) IsApplicationMessage

func (p *Parcel) IsApplicationMessage() bool

IsApplicationMessage checks if the message is intended for the application

func (*Parcel) String

func (p *Parcel) String() string

func (*Parcel) Valid

func (p *Parcel) Valid() error

Valid checks header for inconsistencies

type ParcelChannel

type ParcelChannel chan *Parcel

ParcelChannel is a channel that supports non-blocking sends

func (ParcelChannel) Capacity

func (pc ParcelChannel) Capacity() float64

Capacity returns a percentage [0.0,1.0] of how full the channel is

func (ParcelChannel) Reader

func (pc ParcelChannel) Reader() <-chan *Parcel

Reader returns a read-only channel

func (ParcelChannel) Send

func (pc ParcelChannel) Send(parcel *Parcel) (bool, int)

Send a parcel along this channel. Non-blocking. If full, half of messages are dropped.

type ParcelType

type ParcelType uint16

ParcelType is a list of parcel types that this node understands

const (
	// TypeHeartbeat is deprecated
	TypeHeartbeat ParcelType = iota
	// TypePing is sent if no other parcels have been sent in a while
	TypePing
	// TypePong is a response to a Ping
	TypePong
	// TypePeerRequest indicates a peer wants to be be updated of endpoints
	TypePeerRequest
	// TypePeerResponse carries a payload with protocol specific endpoints
	TypePeerResponse
	// TypeAlert is deprecated
	TypeAlert
	// TypeMessage carries an application message in the payload
	TypeMessage
	// TypeMessagePart is a partial message. deprecated in p2p 2.0
	TypeMessagePart
	// TypeHandshake is the first parcel sent after making a connection
	TypeHandshake
	// TypeRejectAlternative is sent instead of a handshake if the server refuses connection
	TypeRejectAlternative
)

func (ParcelType) String

func (t ParcelType) String() string

type Peer

type Peer struct {

	// current state, read only "constants" after the handshake
	IsIncoming bool
	Endpoint   Endpoint
	NodeID     uint32 // a nonce to distinguish multiple nodes behind one endpoint
	Hash       string // This is more of a connection ID than hash right now.
	// contains filtered or unexported fields
}

Peer is an active connection to an endpoint in the network. Represents one lifetime of a connection and should not be restarted

func (*Peer) Capacity

func (p *Peer) Capacity() float64

Capacity is a wrapper for the send channel's Capacity

func (*Peer) GetMetrics

func (p *Peer) GetMetrics() PeerMetrics

GetMetrics returns live metrics for this connection

func (*Peer) Send

func (p *Peer) Send(parcel *Parcel)

func (*Peer) StartWithHandshake

func (p *Peer) StartWithHandshake(ep Endpoint, con net.Conn, incoming bool) ([]Endpoint, error)

StartWithHandshake performs a basic handshake maneouver to establish the validity of the connection. Immediately sends a Peer Request upon connection and waits for the response, which can be any parcel. The information in the header is verified, especially the port.

The handshake ensures that ALL peers have a valid Port field to start with. If there is no reply within the specified HandshakeTimeout config setting, the process fails

For outgoing connections, it is possible the endpoint will reject due to being full, in which case this function returns an error AND a list of alternate endpoints

func (*Peer) Stop

func (p *Peer) Stop()

Stop disconnects the peer from its active connection

func (*Peer) String

func (p *Peer) String() string

type PeerMetrics

type PeerMetrics struct {
	Hash             string
	PeerAddress      string
	MomentConnected  time.Time
	PeerQuality      int32
	LastReceive      time.Time
	LastSend         time.Time
	MessagesSent     uint64
	BytesSent        uint64
	MessagesReceived uint64
	BytesReceived    uint64
	Incoming         bool
	PeerType         string
	ConnectionState  string
	MPSDown          float64
	MPSUp            float64
	BPSDown          float64
	BPSUp            float64
	Capacity         float64
	Dropped          uint64
}

PeerMetrics is the data shared to the metrics hook

type PeerStore

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

PeerStore holds active Peers, managing them in a concurrency safe manner and providing lookup via various functions

func NewPeerStore

func NewPeerStore() *PeerStore

NewPeerStore initializes a new peer store

func (*PeerStore) Add

func (ps *PeerStore) Add(p *Peer) error

Add a peer to be managed. Throws error if a peer with that hash is already tracked

func (*PeerStore) Connected

func (ps *PeerStore) Connected(ep Endpoint) bool

Connected returns if there is a peer from that specific endpoint

func (*PeerStore) Connections

func (ps *PeerStore) Connections(addr string) int

Connections tests whether there is a peer connected from a specified ip address

func (*PeerStore) Count

func (ps *PeerStore) Count(addr string) int

Count returns the amount of peers connected from a specified ip address

func (*PeerStore) Get

func (ps *PeerStore) Get(hash string) *Peer

Get retrieves a Peer with a specific hash, nil if it doesn't exist

func (*PeerStore) Incoming

func (ps *PeerStore) Incoming() int

Incoming is the amount of incoming peers connected

func (*PeerStore) Outgoing

func (ps *PeerStore) Outgoing() int

Outgoing is the amount of outgoing peers connected

func (*PeerStore) Remove

func (ps *PeerStore) Remove(p *Peer)

Remove a specific peer if it exists. This checks by pointer reference and not by hash. If you have two distinct peer instances (A and B) with the same hash and add A, removing B has no effect, even if they have the same values

func (*PeerStore) Slice

func (ps *PeerStore) Slice() []*Peer

Slice returns a slice of the current peers that is considered concurrency safe for reading operations. The slice should not be modified. Peers are randomly ordered

func (*PeerStore) Total

func (ps *PeerStore) Total() int

Total amount of peers connected

type Persist

type Persist struct {
	Bans      map[string]time.Time `json:"bans"` // can be ip or ip:port
	Bootstrap []Endpoint           `json:"bootstrap"`
}

Persist is the object that gets json-marshalled and written to disk

type Prometheus

type Prometheus struct {
	Networks    prometheus.Gauge
	Connections prometheus.Gauge // done
	Unique      prometheus.Gauge
	Connecting  prometheus.Gauge // done
	Incoming    prometheus.Gauge // done
	Outgoing    prometheus.Gauge // done

	KnownPeers prometheus.Gauge // done

	SendRoutines    prometheus.Gauge
	ReceiveRoutines prometheus.Gauge

	ParcelsSent     prometheus.Counter
	ParcelsReceived prometheus.Counter
	Invalid         prometheus.Counter
	AppSent         prometheus.Counter
	AppReceived     prometheus.Counter
	AppDuplicate    prometheus.Counter

	ParcelSize prometheus.Histogram
}

Prometheus holds all of the prometheus recording instruments

func (*Prometheus) Setup

func (p *Prometheus) Setup()

Setup registers all of the instruments with prometheus once

type Protocol

type Protocol interface {
	Send(p *Parcel) error
	Receive() (*Parcel, error)
	MakePeerShare([]Endpoint) ([]byte, error)
	ParsePeerShare([]byte) ([]Endpoint, error)
	Version() string
}

Protocol is the interface for reading and writing parcels to the underlying connection. The job of a protocol is to encode a Parcel and send it over TCP to another instance of the same Protocol on the other end

Send: Parcel => Protocol Encoder => Protocol Format => TCP Receive: TCP => Protocol Format => Protocol Decoder => Parcel

Peer Sharing creates the protocol specific payload for a TypePeerShare Parcel

Every protocol should be bootstraped in peer:bootstrapProtocol() where it can be initialized with the required serialization methods

type ProtocolV10

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

ProtocolV10 is the protocol introduced by p2p 2.0. It is a slimmed down version of V9, reducing overhead

func (*ProtocolV10) MakePeerShare

func (v10 *ProtocolV10) MakePeerShare(share []Endpoint) ([]byte, error)

MakePeerShare serializes a list of ips via json

func (*ProtocolV10) ParsePeerShare

func (v10 *ProtocolV10) ParsePeerShare(payload []byte) ([]Endpoint, error)

ParsePeerShare parses a peer share payload

func (*ProtocolV10) Receive

func (v10 *ProtocolV10) Receive() (*Parcel, error)

Receive converts a V10Msg back to a Parcel

func (*ProtocolV10) Send

func (v10 *ProtocolV10) Send(p *Parcel) error

Send encodes a Parcel as V10Msg, calculates the crc and encodes it as gob

func (*ProtocolV10) Version

func (v10 *ProtocolV10) Version() string

Version 10

type ProtocolV9

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

ProtocolV9 is the legacy format of the old p2p package which sends Parcels over the wire using gob. The V9Msg struct is equivalent to the old package's "Parcel" and "ParcelHeader" structure

func (*ProtocolV9) MakePeerShare

func (v9 *ProtocolV9) MakePeerShare(ps []Endpoint) ([]byte, error)

MakePeerShare serializes the given endpoints to a V9Share encoded in json

func (*ProtocolV9) ParsePeerShare

func (v9 *ProtocolV9) ParsePeerShare(payload []byte) ([]Endpoint, error)

ParsePeerShare unserializes the json V9Share

func (*ProtocolV9) Receive

func (v9 *ProtocolV9) Receive() (*Parcel, error)

Receive a parcel from the network. Blocking.

func (*ProtocolV9) Send

func (v9 *ProtocolV9) Send(p *Parcel) error

Send a parcel over the connection

func (*ProtocolV9) Version

func (v9 *ProtocolV9) Version() string

Version of the protocol

type ReadWriteCollector

type ReadWriteCollector interface {
	io.Reader
	io.Writer
	StatsCollector
}

type StatsCollector

type StatsCollector interface {
	Collect() (mw uint64, mr uint64, bw uint64, br uint64)
}

type V10Msg

type V10Msg struct {
	Type    ParcelType
	Crc32   uint32
	Payload []byte
}

V10Msg is the barebone message

type V10Share

type V10Share Endpoint

V10Share is an alias of PeerShare

type V9Header

type V9Header struct {
	Network     NetworkID
	Version     uint16
	Type        ParcelType
	Length      uint32
	TargetPeer  string
	Crc32       uint32
	PartNo      uint16
	PartsTotal  uint16
	NodeID      uint64
	PeerAddress string
	PeerPort    string
	AppHash     string
	AppType     string
}

V9Header carries meta information about the parcel

type V9Msg

type V9Msg struct {
	Header  V9Header
	Payload []byte
}

V9Msg is the legacy format of protocol 9

func (V9Msg) Valid

func (msg V9Msg) Valid() error

Valid checks header for inconsistencies

type V9Share

type V9Share struct {
	QualityScore int32
	Address      string
	Port         string
	NodeID       uint64
	Hash         string
	Location     uint32
	Network      NetworkID
	Type         uint8
	Connections  int
	LastContact  time.Time
	Source       map[string]time.Time
}

V9Share is the legacy code's "Peer" struct. Resets QualityScore and Source list when decoding, filters out wrong Networks

Jump to

Keyboard shortcuts

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