p2pcommon

package
v1.11.1 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2019 License: MIT Imports: 14 Imported by: 23

Documentation

Overview

* @file * @copyright defined in aergo/LICENSE.txt

Index

Constants

View Source
const (
	// this magic number is useful only in handshaking
	MAGICMain uint32 = 0x47416841
	MAGICTest uint32 = 0x2e415429

	SigLength = 16

	MaxPayloadLength = 1 << 23 // 8MB

	MaxBlockHeaderResponseCount = 10000
	MaxBlockResponseCount       = 2000
)

constants of p2p protocol since v0.3

View Source
const (
	LegacyP2PSubAddr core.ProtocolID = "/aergop2p/0.3"
	P2PSubAddr       core.ProtocolID = "/aergop2p"
)

context of multiaddr, as higher type of p2p message

View Source
const (
	V030HSHeaderLength = 8
	HSMagicLength      = 4
	HSVersionLength    = 4
	HSVerCntLength     = 4
)

constatns for hanshake. for cacluating byte offset of wire handshake

View Source
const (
	ErrWrongHSReq       uint32
	ErrNoMatchedVersion //

)

Codes in wire handshake

View Source
const (
	DefaultPkKeyPrefix = "aergo-peer"
	DefaultPkKeyExt    = ".key"
	DefaultPubKeyExt   = ".pub"
	DefaultPeerIDExt   = ".id"
)

constants about private key

View Source
const (
	// DesignatedNodeTTL is time to determine which the remote designated peer is not working.
	DesignatedNodeTTL = time.Minute * 60

	// DefaultNodeTTL is time to determine which the remote peer is not working.
	DefaultNodeTTL = time.Minute * 10
)
View Source
const (
	WaitingPeerManagerInterval = time.Minute

	PolarisQueryInterval = time.Minute * 10
	PeerQueryInterval    = time.Hour
	PeerFirstInterval    = time.Second * 4

	MaxConcurrentHandshake = 5
)
View Source
const (
	// other actor
	DefaultActorMsgTTL = time.Second * 4
)

constants for inter-communication of aergosvr

View Source
const HSError uint32 = 0
View Source
const HSMaxVersionCnt = 16
View Source
const IDLength = 16
View Source
const (
	UnknownVersion = ""
)

Variables

View Source
var (
	EmptyID = MsgID(uuid.Nil)
)
View Source
var (
	ErrNoWaitings = errors.New("no waiting peer exists")
)

Functions

This section is empty.

Types

type ActorService

type ActorService interface {
	// TellRequest send actor request, which does not need to get return value, and forget it.
	TellRequest(actor string, msg interface{})
	// SendRequest send actor request, and the response is expected to go back asynchronously.
	SendRequest(actor string, msg interface{})
	// CallRequest send actor request and wait the handling of that message to finished,
	// and get return value.
	CallRequest(actor string, msg interface{}, timeout time.Duration) (interface{}, error)
	// CallRequestDefaultTimeout is CallRequest with default timeout
	CallRequestDefaultTimeout(actor string, msg interface{}) (interface{}, error)

	// FutureRequest send actor reqeust and get the Future object to get the state and return value of message
	FutureRequest(actor string, msg interface{}, timeout time.Duration) *actor.Future
	// FutureRequestDefaultTimeout is FutureRequest with default timeout
	FutureRequestDefaultTimeout(actor string, msg interface{}) *actor.Future

	GetChainAccessor() types.ChainAccessor
}

ActorService is collection of helper methods to use actor FIXME move to more general package. it used in p2p and rpc

type ConnWorkResult

type ConnWorkResult struct {
	Inbound bool
	Seq     uint32
	// TargetPeer is nil if Inbound is true
	TargetPeer *WaitingPeer
	Meta       PeerMeta

	P2PVer uint32
	Result error
}

type FlushableWriter

type FlushableWriter interface {
	io.Writer
	// Flush writes any buffered data to the underlying io.Writer.
	Flush() error
}

FlushableWriter is writer which have Flush method, such as bufio.Writer

type HSHandler

type HSHandler interface {
	// Handle peer handshake till ttl, and return msgrw for this connection, and status of remote peer.
	Handle(r io.Reader, w io.Writer, ttl time.Duration) (MsgReadWriter, *types.Status, error)
}

HSHandler handles whole process of connect, handshake, create of remote Peerseer

type HSHandlerFactory

type HSHandlerFactory interface {
	CreateHSHandler(p2pVersion P2PVersion, outbound bool, pid types.PeerID) HSHandler
}

HSHandlerFactory is creator of HSHandler

type HSHeadReq

type HSHeadReq struct {
	Magic uint32
	// Versions are p2p versions which the connecting peer can support.
	Versions []P2PVersion
}

HSHeadReq is data which peer send first to listening peer in wire handshake

func (HSHeadReq) Marshal

func (h HSHeadReq) Marshal() []byte

type HSHeadResp

type HSHeadResp struct {
	// Magic will be same as the magic in HSHeadReq if wire handshake is successful, or 0 if not.
	Magic uint32
	// RespCode is different meaning by value of Magic. It is p2p version which listening peer will use, if wire handshake is succesful, or errCode otherwise.
	RespCode uint32
}

HSHeadResp is data which listening peer send back to connecting peer as response

func (HSHeadResp) Marshal

func (h HSHeadResp) Marshal() []byte

func (*HSHeadResp) Unmarshal

func (h *HSHeadResp) Unmarshal(b []byte)

type HSHeader

type HSHeader struct {
	Magic   uint32
	Version P2PVersion
}

HSHeader is legacy type of data which peer send first to listening peer in wire handshake

func (HSHeader) Marshal

func (h HSHeader) Marshal() []byte

func (*HSHeader) Unmarshal

func (h *HSHeader) Unmarshal(b []byte)

type HandlerFactory

type HandlerFactory interface {
	InsertHandlers(peer RemotePeer)
}

type Message

type Message interface {
	Subprotocol() SubProtocol

	// Length is lentgh of payload
	Length() uint32

	// Timestamp is when this message was created with unixnano format
	Timestamp() int64

	// ID is 16 bytes unique identifier
	ID() MsgID

	// OriginalID is message id of request which trigger this message. it will be all zero, if message is request or notice.
	OriginalID() MsgID

	// Payload is MessageBody struct, marshaled by google protocol buffer v3. object is determined by Subprotocol
	Payload() []byte
}

Message is unit structure transferred from a peer to another peer.

type MessageBody

type MessageBody interface {
	proto.Message
}

MessageBody is content of p2p message. The actual data types are varied by subprotocol, so For version 0.3.x, it is just wrapper of proto.Message

type MessageHandler

type MessageHandler interface {
	ParsePayload([]byte) (MessageBody, error)
	CheckAuth(msg Message, msgBody MessageBody) error
	Handle(msg Message, msgBody MessageBody)
	PreHandle()
	PostHandle(msg Message, msgBody MessageBody)
}

MessageHandler handle incoming message

type MessageValue

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

MessageValue is basic implementation of Message. It is used since p2p v0.3

func NewLiteMessageValue

func NewLiteMessageValue(protocol SubProtocol, msgID, originalID MsgID, timestamp int64) *MessageValue

NewLiteMessageValue create MessageValue object which payload is empty

func NewMessageValue

func NewMessageValue(protocol SubProtocol, msgID, originalID MsgID, timestamp int64, payload []byte) *MessageValue

NewMessageValue create a new object

func NewSimpleMsgVal

func NewSimpleMsgVal(protocol SubProtocol, msgID MsgID) *MessageValue

func NewSimpleRespMsgVal

func NewSimpleRespMsgVal(protocol SubProtocol, msgID MsgID, originalID MsgID) *MessageValue

func (*MessageValue) ID

func (m *MessageValue) ID() MsgID

func (*MessageValue) Length

func (m *MessageValue) Length() uint32

func (*MessageValue) OriginalID

func (m *MessageValue) OriginalID() MsgID

func (*MessageValue) Payload

func (m *MessageValue) Payload() []byte

func (*MessageValue) SetPayload

func (m *MessageValue) SetPayload(payload []byte)

func (*MessageValue) Subprotocol

func (m *MessageValue) Subprotocol() SubProtocol

func (*MessageValue) Timestamp

func (m *MessageValue) Timestamp() int64

type MoFactory

type MoFactory interface {
	NewMsgRequestOrder(expecteResponse bool, protocolID SubProtocol, message MessageBody) MsgOrder
	NewMsgBlockRequestOrder(respReceiver ResponseReceiver, protocolID SubProtocol, message MessageBody) MsgOrder
	NewMsgResponseOrder(reqID MsgID, protocolID SubProtocol, message MessageBody) MsgOrder
	NewMsgBlkBroadcastOrder(noticeMsg *types.NewBlockNotice) MsgOrder
	NewMsgTxBroadcastOrder(noticeMsg *types.NewTransactionsNotice) MsgOrder
	NewMsgBPBroadcastOrder(noticeMsg *types.BlockProducedNotice) MsgOrder
}

type MsgID

type MsgID [IDLength]byte

MsgID is

func MustParseBytes

func MustParseBytes(b []byte) MsgID

MustParseBytes return msgid from byte slice

func NewMsgID

func NewMsgID() (m MsgID)

NewMsgID return random id

func ParseBytesToMsgID

func ParseBytesToMsgID(b []byte) (MsgID, error)

func (MsgID) String

func (id MsgID) String() string

func (MsgID) UUID

func (id MsgID) UUID() uuid.UUID

type MsgOrder

type MsgOrder interface {
	GetMsgID() MsgID
	// Timestamp is unit time value
	Timestamp() int64
	IsRequest() bool
	IsNeedSign() bool
	GetProtocolID() SubProtocol

	// SendTo send message to remote peer. it return err if write fails, or nil if write is successful or ignored.
	SendTo(p RemotePeer) error
}

MsgOrder is abstraction of information about the message that will be sent to peer. Some type of msgOrder, such as notice mo, should thread-safe and re-entrant

type MsgReadWriter

type MsgReadWriter interface {
	MsgReader
	MsgWriter
}

type MsgReader

type MsgReader interface {
	// ReadMsg return types.MsgHeader as header, MessageBody as data
	// The header and/or data can be nil if error is not nil
	ReadMsg() (Message, error)
}

MsgReader read byte stream, parse stream with respect to protocol version and return message object used in p2p module

type MsgSigner

type MsgSigner interface {
	// signMsg calulate signature and fill related fields in msg(peerid, pubkey, signature or etc)
	SignMsg(msg *types.P2PMessage) error
	// verifyMsg check signature is valid
	VerifyMsg(msg *types.P2PMessage, senderID types.PeerID) error
}

MsgSigner sign or verify p2p message this is not used since v0.3, but interface is not removed for future version.

type MsgWriter

type MsgWriter interface {
	WriteMsg(msg Message) error
}

MsgWriter write message to stream

type NTContainer

type NTContainer interface {
	GetNetworkTransport() NetworkTransport

	// ChainID return id of current chain.
	ChainID() *types.ChainID
}

NTContainer can provide NetworkTransport interface.

type NetworkTransport

type NetworkTransport interface {
	core.Host
	Start() error
	Stop() error

	SelfMeta() PeerMeta

	GetAddressesOfPeer(peerID types.PeerID) []string

	// AddStreamHandler wrapper function which call host.SetStreamHandler after transport is initialized, this method is for preventing nil error.
	AddStreamHandler(pid core.ProtocolID, handler network.StreamHandler)

	GetOrCreateStream(meta PeerMeta, protocolIDs ...core.ProtocolID) (core.Stream, error)
	GetOrCreateStreamWithTTL(meta PeerMeta, ttl time.Duration, protocolIDs ...core.ProtocolID) (core.Stream, error)

	FindPeer(peerID types.PeerID) bool
	ClosePeerConnection(peerID types.PeerID) bool
}

NetworkTransport do manager network connection TODO need refactoring. it has other role, pk management of self peer

type P2PVersion

type P2PVersion uint32

P2PVersion is verion of p2p wire protocol. This version affects p2p handshake, data format transferred, etc

const (
	P2PVersionUnknown P2PVersion = 0x00000000
	P2PVersion030     P2PVersion = 0x00000300
	P2PVersion031     P2PVersion = 0x00000301 // pseudo version for supporting multiversion
)

func (P2PVersion) String

func (v P2PVersion) String() string

func (P2PVersion) Uint32

func (v P2PVersion) Uint32() uint32

type PeerAccessor

type PeerAccessor interface {
	GetPeerBlockInfos() []types.PeerBlockInfo
	GetPeer(ID types.PeerID) (RemotePeer, bool)
}

PeerAccessor is an interface for a another actor module to get info of peers

type PeerEventListener

type PeerEventListener interface {
	OnPeerConnect(pid types.PeerID)
	OnPeerDisconnect(peer RemotePeer)
}

type PeerFinder

type PeerFinder interface {
	PeerEventListener

	// Check if it need to discover more peers and send query request to polaris or other peers if needed.
	CheckAndFill()
}

PeerFinder works for collecting peer candidate. It queries to Polaris or other connected peer efficiently. It determine if peer is NOTE that this object is not thread safe by itself.

type PeerManager

type PeerManager interface {
	Start() error
	Stop() error

	//NetworkTransport
	SelfMeta() PeerMeta
	SelfNodeID() types.PeerID

	AddNewPeer(peer PeerMeta)
	// Remove peer from peer list. Peer dispose relative resources and stop itself, and then call RemovePeer to peermanager
	RemovePeer(peer RemotePeer)

	NotifyPeerAddressReceived([]PeerMeta)

	// GetPeer return registered(handshaked) remote peer object
	GetPeer(ID types.PeerID) (RemotePeer, bool)
	GetPeers() []RemotePeer
	GetPeerAddresses(noHidden bool, showSelf bool) []*message.PeerInfo

	GetPeerBlockInfos() []types.PeerBlockInfo
}

PeerManager is internal service that provide peer management

type PeerMeta

type PeerMeta struct {
	ID types.PeerID
	// IPAddress is human readable form of ip address such as "192.168.0.1" or "2001:0db8:0a0b:12f0:33:1"
	IPAddress  string
	Port       uint32
	Designated bool // Designated means this peer is designated in config file and connect to in startup phase

	Version  string
	Hidden   bool // Hidden means that meta info of this peer will not be sent to other peers when getting peer list
	Outbound bool
}

PeerMeta contains non changeable information of peer node during connected state

func FromPeerAddress

func FromPeerAddress(addr *types.PeerAddress) PeerMeta

FromPeerAddress convert PeerAddress to PeerMeta

func NewMetaFromStatus

func NewMetaFromStatus(status *types.Status, outbound bool) PeerMeta

FromStatusToMeta create peerMeta from Status message

func (*PeerMeta) GetVersion

func (m *PeerMeta) GetVersion() string

func (PeerMeta) ToPeerAddress

func (m PeerMeta) ToPeerAddress() types.PeerAddress

ToPeerAddress convert PeerMeta to PeerAddress

type RemotePeer

type RemotePeer interface {
	ID() types.PeerID
	Meta() PeerMeta
	ManageNumber() uint32
	Name() string
	Version() string

	AddMessageHandler(subProtocol SubProtocol, handler MessageHandler)

	State() types.PeerState
	// LastStatus returns last observed status of remote peer. this value will be changed by notice, or ping
	LastStatus() *types.LastBlockStatus

	RunPeer()
	Stop()

	SendMessage(msg MsgOrder)
	SendAndWaitMessage(msg MsgOrder, ttl time.Duration) error

	PushTxsNotice(txHashes []types.TxID)

	ConsumeRequest(msgID MsgID)
	GetReceiver(id MsgID) ResponseReceiver

	// updateBlkCache add hash to block cache and return true if this hash already exists.
	UpdateBlkCache(blkHash []byte, blkNumber uint64) bool
	// updateTxCache add hashes to transaction cache and return newly added hashes.
	UpdateTxCache(hashes []types.TxID) []types.TxID
	// updateLastNotice change estimate of the last status of remote peer
	UpdateLastNotice(blkHash []byte, blkNumber uint64)

	// TODO
	MF() MoFactory
}

type ResponseReceiver

type ResponseReceiver func(Message, MessageBody) bool

ResponseReceiver is handler function for the corresponding response message. It returns true when receiver handled it, or false if this receiver is not the expected handler.

type SubProtocol

type SubProtocol uint32

SubProtocol identifies the lower type of p2p message

func (SubProtocol) String

func (i SubProtocol) String() string

func (SubProtocol) Uint32

func (i SubProtocol) Uint32() uint32

type SyncManager

type SyncManager interface {
	// handle notice from bp
	HandleBlockProducedNotice(peer RemotePeer, block *types.Block)
	// handle notice from other node
	HandleNewBlockNotice(peer RemotePeer, data *types.NewBlockNotice)
	HandleGetBlockResponse(peer RemotePeer, msg Message, resp *types.GetBlockResponse)
	HandleNewTxNotice(peer RemotePeer, hashes []types.TxID, data *types.NewTransactionsNotice)
}

type VersionedHandshaker

type VersionedHandshaker interface {
	DoForOutbound(ctx context.Context) (*types.Status, error)
	DoForInbound(ctx context.Context) (*types.Status, error)
	GetMsgRW() MsgReadWriter
}

VersionedHandshaker do handshake related to chain, and return msgreadwriter for a protocol version. It is used inside HSHandler

type VersionedManager

type VersionedManager interface {
	FindBestP2PVersion(versions []P2PVersion) P2PVersion
	GetVersionedHandshaker(version P2PVersion, peerID types.PeerID, r io.Reader, w io.Writer) (VersionedHandshaker, error)

	InjectHandlers(version P2PVersion, peer RemotePeer)
}

type WaitingPeer

type WaitingPeer struct {
	Meta      PeerMeta
	TrialCnt  int
	NextTrial time.Time

	LastResult error
}

type WaitingPeerManager

type WaitingPeerManager interface {
	PeerEventListener
	// OnDiscoveredPeers is called when response of discover query came from polaris or other peer.
	// It returns the count of previously unknown peers.
	OnDiscoveredPeers(metas []PeerMeta) int
	// OnWorkDone
	OnWorkDone(result ConnWorkResult)

	CheckAndConnect()

	OnInboundConn(s network.Stream)

	OnInboundConnLegacy(s network.Stream)
}

WaitingPeerManager manage waiting peer pool and role to connect and handshaking of remote peer.

Jump to

Keyboard shortcuts

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