Documentation
¶
Overview ¶
Package peer provides a common base for creating and managing Decred network peers.
This package builds upon the wire package, which provides the fundamental primitives necessary to speak the Decred wire protocol, in order to simplify the process of creating fully functional peers. In essence, it provides a common base for creating concurrent safe fully validating nodes, Simplified Payment Verification (SPV) nodes, proxies, etc.
A quick overview of the major features peer provides are as follows:
- Provides a basic concurrent safe Decred peer for handling decred communications via the peer-to-peer protocol
- Full duplex reading and writing of Decred protocol messages
- Automatic handling of the initial handshake process including protocol version negotiation
- Asynchronous message queuing of outbound messages with optional channel for notification when the message is actually sent
- Flexible peer configuration
- Caller is responsible for creating outgoing connections and listening for incoming connections so they have flexibility to establish connections as they see fit (proxies, etc)
- User agent name and version
- Decred network
- Service support signalling (full nodes, etc)
- Maximum supported protocol version
- Ability to register callbacks for handling Decred protocol messages
- Inventory message batching and send trickling with known inventory detection and avoidance
- Automatic periodic keep-alive pinging and pong responses
- Random nonce generation and self connection detection
- Snapshottable peer statistics such as the total number of bytes read and written, the remote address, user agent, and negotiated protocol version
- Helper functions pushing addresses, getblocks, getheaders, and reject messages
- The aforementioned messages could all be sent manually via the standard message output function, but the helpers provide additional nice functionality such as duplicate filtering and address randomization
- Ability to wait for shutdown/disconnect
- Comprehensive test coverage
Peer Configuration ¶
All peer configuration is handled with the Config struct. This allows the caller to specify things such as the user agent name and version, the decred network to use, which services it supports, and callbacks to invoke when decred messages are received. See the documentation for each field of the Config struct for more details.
Inbound and Outbound Peers ¶
A peer can either be inbound or outbound. The caller is responsible for establishing the connection to remote peers and listening for incoming peers. This provides high flexibility for things such as connecting via proxies, acting as a proxy, creating bridge peers, choosing whether to listen for inbound peers, etc.
NewOutboundPeer and NewInboundPeer must be followed by calling Peer.Handshake on the returned instance to perform the initial protocol negotiation handshake process and finally Peer.Run to start all async I/O goroutines and block until peer disconnection and resource cleanup has completed.
When finished with the peer, call Peer.Disconnect or cancel the context provided to Peer.Run to close the connection and clean up all resources.
Callbacks ¶
In order to do anything useful with a peer, it is necessary to react to decred messages. This is accomplished by creating an instance of the MessageListeners struct with the callbacks to be invoke specified and setting [Config.Listeners] in the Config struct specified when creating a peer.
For convenience, a callback hook for all of the currently supported decred messages is exposed which receives the peer instance and the concrete message type. In addition, a [MessageListeners.OnRead] hook is provided so even custom messages types for which this package does not directly provide a hook, as long as they implement the wire.Message interface, can be used. Finally, the [MessageListeners.OnWrite] hook is provided, which in conjunction with [MessageListeners.OnRead], can be used to track server-wide byte counts.
It is often useful to use closures which encapsulate state when specifying the callback handlers. This provides a clean method for accessing that state when callbacks are invoked.
Queuing Messages and Inventory ¶
The Peer.QueueMessage function provides the fundamental means to send messages to the remote peer. As the name implies, this employs a non-blocking queue. A done channel which will be notified when the message is actually sent can optionally be specified. There are certain message types which are better sent using other functions which provide additional functionality.
Of special interest are inventory messages. Rather than manually sending MsgInv messages via Peer.QueueMessage, the inventory vectors should be queued using the Peer.QueueInventory function. It employs batching and trickling along with intelligent known remote peer inventory detection and avoidance through the use of a most-recently used algorithm.
Message Sending Helper Functions ¶
In addition to the bare Peer.QueueMessage function previously described, the Peer.PushAddrMsg, Peer.PushGetBlocksMsg, and Peer.PushGetHeadersMsg functions are provided as a convenience. While it is of course possible to create and send these messages manually via Peer.QueueMessage, these helper functions provided additional useful functionality that is typically desired.
For example, Peer.PushAddrMsg automatically limits the addresses to the maximum number allowed by the message and randomizes the chosen addresses when there are too many. This allows the caller to simply provide a slice of known addresses, such as that returned by the addrmgr package, without having to worry about the details.
Finally, Peer.PushGetBlocksMsg and Peer.PushGetHeadersMsg will construct proper messages using a block locator and ignore back to back duplicate requests.
Peer Statistics ¶
A snapshot of the current peer statistics can be obtained with Peer.StatsSnapshot. This includes statistics such as the total number of bytes read and written, the remote address, user agent, and negotiated protocol version.
Logging ¶
This package provides extensive logging capabilities through the UseLogger function which allows a slog.Logger to be specified. For example, logging at the debug level provides summaries of every message sent and received, and logging at the trace level provides full dumps of parsed messages as well as the raw message bytes using a format similar to hexdump -C.
Decred Change Proposals ¶
This package supports all Decred Change Proposals (DCPs) supported by the wire package.
Example (NewOutboundPeer) ¶
This example demonstrates the basic process for initializing and creating an outbound peer. Peers negotiate by exchanging version and verack messages. For demonstration, a simple handler for version message is attached to the peer.
package main
import (
"context"
"fmt"
"net"
"time"
"github.com/decred/dcrd/crypto/rand"
"github.com/decred/dcrd/peer/v4"
"github.com/decred/dcrd/wire"
)
// mockRemotePeer creates a basic inbound peer listening on the simnet port for
// use with Example_peerConnection. It does not return until the listener is
// active.
func mockRemotePeer(listenAddr string) (net.Listener, error) {
// Configure peer to act as a simnet node that offers no services.
peerCfg := &peer.Config{
UserAgentName: "peer", // User agent name to advertise.
UserAgentVersion: "1.0.0", // User agent version to advertise.
Net: wire.SimNet,
IdleTimeout: time.Second * 120,
}
// Accept connections on the simnet port.
listener, err := net.Listen("tcp", listenAddr)
if err != nil {
return nil, err
}
go func() {
conn, err := listener.Accept()
if err != nil {
fmt.Printf("Accept: error %v\n", err)
return
}
// Create and start the inbound peer.
go func() {
p := peer.NewInboundPeer(peerCfg, conn)
if err := p.Handshake(context.Background(), nil); err != nil {
fmt.Printf("inbound handshake error: %v\n", err)
return
}
p.Run(context.Background())
}()
}()
return listener, nil
}
// This example demonstrates the basic process for initializing and creating an
// outbound peer. Peers negotiate by exchanging version and verack messages.
// For demonstration, a simple handler for version message is attached to the
// peer.
func main() {
// Ordinarily this will not be needed since the outbound peer will be
// connecting to a remote peer, however, since this example is executed
// and tested, a mock remote peer is needed to listen for the outbound
// peer.
listener, err := mockRemotePeer("127.0.0.1:18555")
if err != nil {
fmt.Printf("mockRemotePeer: unexpected error %v\n", err)
return
}
defer listener.Close()
// Establish the connection to the peer address.
conn, err := net.Dial("tcp", listener.Addr().String())
if err != nil {
fmt.Printf("net.Dial: error %v\n", err)
return
}
// Create an outbound peer that is configured to act as a simnet node
// that offers no services and has a listener for the pong message.
//
// Then perform the initial handshake and start the async I/O handling.
//
// The pong listener is used here to signal the code below when it arrives
// in response to an example ping.
pong := make(chan struct{})
peerCfg := &peer.Config{
UserAgentName: "peer", // User agent name to advertise.
UserAgentVersion: "1.0.0", // User agent version to advertise.
Net: wire.SimNet,
Services: 0,
Listeners: peer.MessageListeners{
// This uses a simple channel for the purposes of the example, but
// callers will typically find it much more ergonomic to create a
// type that houses additional state and exposes methods for the
// desired listeners. Then the listeners may be set to a concrete
// instance of that type so that they close over the additional
// state.
OnPong: func(p *peer.Peer, msg *wire.MsgPong) {
pong <- struct{}{}
},
},
IdleTimeout: time.Second * 120,
}
p := peer.NewOutboundPeer(peerCfg, conn.RemoteAddr(), conn)
ctx := context.Background()
if err := p.Handshake(ctx, nil); err != nil {
fmt.Printf("outbound peer handshake error: %v\n", err)
return
}
go p.Run(ctx)
defer p.Disconnect()
// Ping the remote peer aysnchronously.
p.QueueMessage(wire.NewMsgPing(rand.Uint64()), nil)
// Wait for the pong message or timeout in case of failure.
select {
case <-pong:
fmt.Println("outbound: received pong")
case <-time.After(time.Second * 1):
fmt.Printf("Example_newOutboundPeer: pong timeout")
}
}
Output: outbound: received pong
Index ¶
- Constants
- func UseLogger(logger slog.Logger)
- type AddrFunc
- type Config
- type Error
- type ErrorKind
- type HashFunc
- type HostToNetAddrFunc
- type MessageListeners
- type OnVersionCallback
- type Peer
- func (p *Peer) AddKnownInventory(invVect *wire.InvVect)
- func (p *Peer) Addr() string
- func (p *Peer) BytesReceived() uint64
- func (p *Peer) BytesSent() uint64
- func (p *Peer) Connected() bool
- func (p *Peer) Disconnect()
- func (p *Peer) Handshake(ctx context.Context, onVersion OnVersionCallback) error
- func (p *Peer) ID() int32
- func (p *Peer) Inbound() bool
- func (p *Peer) IsKnownInventory(invVect *wire.InvVect) bool
- func (p *Peer) LastBlock() int64
- func (p *Peer) LastPingMicros() int64
- func (p *Peer) LastPingNonce() uint64
- func (p *Peer) LastPingTime() time.Time
- func (p *Peer) LastRecv() time.Time
- func (p *Peer) LastSend() time.Time
- func (p *Peer) LocalAddr() net.Addr
- func (p *Peer) ProtocolVersion() uint32
- func (p *Peer) PushAddrMsg(addresses []*wire.NetAddress) ([]*wire.NetAddress, error)
- func (p *Peer) PushAddrV2Msg(addresses []wire.NetAddressV2) []wire.NetAddressV2
- func (p *Peer) PushGetBlocksMsg(locator []chainhash.Hash, stopHash *chainhash.Hash) error
- func (p *Peer) PushGetHeadersMsg(locator []chainhash.Hash, stopHash *chainhash.Hash) error
- func (p *Peer) QueueInventory(invVect *wire.InvVect)
- func (p *Peer) QueueInventoryImmediate(invVect *wire.InvVect)
- func (p *Peer) QueueMessage(msg wire.Message, doneChan chan<- struct{})
- func (p *Peer) Run(ctx context.Context)
- func (p *Peer) Services() wire.ServiceFlag
- func (p *Peer) StartingHeight() int64
- func (p *Peer) StatsSnapshot() *StatsSnap
- func (p *Peer) String() string
- func (p *Peer) TimeConnected() time.Time
- func (p *Peer) TimeOffset() int64
- func (p *Peer) UpdateLastBlockHeight(newHeight int64)
- func (p *Peer) UserAgent() string
- func (p *Peer) WaitForDisconnect()
- func (p *Peer) WantsHeaders() bool
- type StatsSnap
Examples ¶
Constants ¶
const ( // ErrNotVersionMessage indicates the first message received from a remote // peer is not the required version message. ErrNotVersionMessage = ErrorKind("ErrNotVersionMessage") // ErrSelfConnection indicates a peer attempted to connect to itself. ErrSelfConnection = ErrorKind("ErrSelfConnection") // ErrProtocolVerTooOld indicates a protocol version is older than the // minimum required version. ErrProtocolVerTooOld = ErrorKind("ErrProtocolVerTooOld") // ErrNotVerAckMessage indicates the second message received from a remote // peer is not the required verack message. ErrNotVerAckMessage = ErrorKind("ErrNotVerAckMessage") // ErrHandshakeTimeout indicates the initial handshake timed out before // completing. ErrHandshakeTimeout = ErrorKind("ErrHandshakeTimeout") )
These constants are used to identify a specific Error.
const ( // MaxProtocolVersion is the max protocol version the peer supports. MaxProtocolVersion = wire.AddrV2Version )
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AddrFunc ¶
type AddrFunc func(remoteAddr *wire.NetAddress) *wire.NetAddress
AddrFunc is a func which takes an address and returns a related address.
type Config ¶
type Config struct {
// NewestBlock specifies a callback which provides the newest block
// details to the peer as needed. This can be nil in which case the
// peer will report a block height of 0, however it is good practice for
// peers to specify this so their currently best known is accurately
// reported.
NewestBlock HashFunc
// HostToNetAddress returns the netaddress for the given host. This can be
// nil in which case the host will be parsed as an IP address.
HostToNetAddress HostToNetAddrFunc
// Proxy indicates a proxy is being used for connections. The only
// effect this has is to prevent leaking the tor proxy address, so it
// only needs to be specified if using a tor proxy.
Proxy string
// UserAgentName specifies the user agent name to advertise. It is
// highly recommended to specify this value.
UserAgentName string
// UserAgentVersion specifies the user agent version to advertise. It
// is highly recommended to specify this value and that it follows the
// form "major.minor.revision" e.g. "2.6.41".
UserAgentVersion string
// UserAgentComments specifies any additional comments to include the in
// user agent to advertise. This is optional, so it may be nil. If
// specified, the comments should only exist of characters from the
// semantic alphabet [a-zA-Z0-9-].
UserAgentComments []string
// Net identifies the network the peer is associated with. It is
// highly recommended to specify this field, but it can be omitted in
// which case the test network will be used.
Net wire.CurrencyNet
// Services specifies which services to advertise as supported by the
// local peer. This field can be omitted in which case it will be 0
// and therefore advertise no supported services.
Services wire.ServiceFlag
// ProtocolVersion specifies the maximum protocol version to use and
// advertise. This field can be omitted in which case
// peer.MaxProtocolVersion will be used.
ProtocolVersion uint32
// DisableRelayTx specifies if the remote peer should be informed to
// not send inv messages for transactions.
DisableRelayTx bool
// Listeners houses callback functions to be invoked on receiving peer
// messages.
Listeners MessageListeners
// IdleTimeout is the duration of inactivity before a peer is timed
// out in seconds.
IdleTimeout time.Duration
}
Config is the struct to hold configuration options useful to Peer.
type Error ¶
Error identifies an address manager error. It has full support for errors.Is and errors.As, so the caller can ascertain the specific reason for the error by checking the underlying error.
type ErrorKind ¶
type ErrorKind string
ErrorKind identifies a kind of error. It has full support for errors.Is and errors.As, so the caller can directly check against an error kind when determining the reason for an error.
type HashFunc ¶
HashFunc is a function which returns a block hash, height and error It is used as a callback to get newest block details.
type HostToNetAddrFunc ¶
type HostToNetAddrFunc func(host string, port uint16, services wire.ServiceFlag) (*wire.NetAddressV2, error)
HostToNetAddrFunc is a func which takes a host, port, services and returns the netaddress.
type MessageListeners ¶
type MessageListeners struct {
// OnGetAddr is invoked when a peer receives a getaddr wire message.
OnGetAddr func(p *Peer, msg *wire.MsgGetAddr)
// OnAddr is invoked when a peer receives an addr wire message.
OnAddr func(p *Peer, msg *wire.MsgAddr)
// OnAddrV2 is invoked when a peer receives an addrv2 wire message.
OnAddrV2 func(p *Peer, msg *wire.MsgAddrV2)
// OnPing is invoked when a peer receives a ping wire message.
OnPing func(p *Peer, msg *wire.MsgPing)
// OnPong is invoked when a peer receives a pong wire message.
OnPong func(p *Peer, msg *wire.MsgPong)
// OnMemPool is invoked when a peer receives a mempool wire message.
OnMemPool func(p *Peer, msg *wire.MsgMemPool)
// OnGetMiningState is invoked when a peer receives a getminings wire
// message.
OnGetMiningState func(p *Peer, msg *wire.MsgGetMiningState)
// OnMiningState is invoked when a peer receives a miningstate wire
// message.
OnMiningState func(p *Peer, msg *wire.MsgMiningState)
// OnTx is invoked when a peer receives a tx wire message.
OnTx func(p *Peer, msg *wire.MsgTx)
// OnBlock is invoked when a peer receives a block wire message.
OnBlock func(p *Peer, msg *wire.MsgBlock, buf []byte)
// OnCFilter is invoked when a peer receives a cfilter wire message.
OnCFilter func(p *Peer, msg *wire.MsgCFilter)
// OnCFilterV2 is invoked when a peer receives a cfilterv2 wire message.
OnCFilterV2 func(p *Peer, msg *wire.MsgCFilterV2)
// OnCFiltersV2 is invoked when a peer receives a cfiltersv2 wire message.
OnCFiltersV2 func(p *Peer, msg *wire.MsgCFiltersV2)
// OnCFHeaders is invoked when a peer receives a cfheaders wire
// message.
OnCFHeaders func(p *Peer, msg *wire.MsgCFHeaders)
// OnCFTypes is invoked when a peer receives a cftypes wire message.
OnCFTypes func(p *Peer, msg *wire.MsgCFTypes)
// OnInv is invoked when a peer receives an inv wire message.
OnInv func(p *Peer, msg *wire.MsgInv)
// OnHeaders is invoked when a peer receives a headers wire message.
OnHeaders func(p *Peer, msg *wire.MsgHeaders)
// OnNotFound is invoked when a peer receives a notfound wire message.
OnNotFound func(p *Peer, msg *wire.MsgNotFound)
// OnGetData is invoked when a peer receives a getdata wire message.
OnGetData func(p *Peer, msg *wire.MsgGetData)
// OnGetBlocks is invoked when a peer receives a getblocks wire message.
OnGetBlocks func(p *Peer, msg *wire.MsgGetBlocks)
// OnGetHeaders is invoked when a peer receives a getheaders wire
// message.
OnGetHeaders func(p *Peer, msg *wire.MsgGetHeaders)
// OnGetCFilter is invoked when a peer receives a getcfilter wire
// message.
OnGetCFilter func(p *Peer, msg *wire.MsgGetCFilter)
// OnGetCFilterV2 is invoked when a peer receives a getcfilterv2 wire
// message.
OnGetCFilterV2 func(p *Peer, msg *wire.MsgGetCFilterV2)
// OnGetCFiltersV2 is invoked when a peer receives a getcfsv2 wire
// message.
OnGetCFiltersV2 func(p *Peer, msg *wire.MsgGetCFsV2)
// OnGetCFHeaders is invoked when a peer receives a getcfheaders
// wire message.
OnGetCFHeaders func(p *Peer, msg *wire.MsgGetCFHeaders)
// OnGetCFTypes is invoked when a peer receives a getcftypes wire
// message.
OnGetCFTypes func(p *Peer, msg *wire.MsgGetCFTypes)
// OnFeeFilter is invoked when a peer receives a feefilter wire message.
OnFeeFilter func(p *Peer, msg *wire.MsgFeeFilter)
// OnSendHeaders is invoked when a peer receives a sendheaders wire
// message.
OnSendHeaders func(p *Peer, msg *wire.MsgSendHeaders)
// OnGetInitState is invoked when a peer receives a getinitstate wire
// message.
OnGetInitState func(p *Peer, msg *wire.MsgGetInitState)
// OnInitState is invoked when a peer receives an initstate message.
OnInitState func(p *Peer, msg *wire.MsgInitState)
// OnMixPairReq is invoked when a peer receives a mixpairreq message.
OnMixPairReq func(p *Peer, msg *wire.MsgMixPairReq)
// OnMixKeyExchange is invoked when a peer receives a mixkeyxchg message.
OnMixKeyExchange func(p *Peer, msg *wire.MsgMixKeyExchange)
// OnMixCiphertexts is invoked when a peer receives a mixcphrtxt message.
OnMixCiphertexts func(p *Peer, msg *wire.MsgMixCiphertexts)
// OnMixSlotReserve is invoked when a peer receives a mixslotres message.
OnMixSlotReserve func(p *Peer, msg *wire.MsgMixSlotReserve)
// OnMixDCNet is invoked when a peer receives a mixdcnet message.
OnMixDCNet func(p *Peer, msg *wire.MsgMixDCNet)
// OnMixConfirm is invoked when a peer receives a mixconfirm message.
OnMixConfirm func(p *Peer, msg *wire.MsgMixConfirm)
// OnMixFactoredPoly is invoked when a peer receives a mixfactpoly message.
OnMixFactoredPoly func(p *Peer, msg *wire.MsgMixFactoredPoly)
// OnMixSecrets is invoked when a peer receives a mixsecrets message.
OnMixSecrets func(p *Peer, msg *wire.MsgMixSecrets)
// OnRead is invoked when a peer receives a wire message. It consists
// of the number of bytes read, the message, and whether or not an error
// in the read occurred. Typically, callers will opt to use the
// callbacks for the specific message types, however this can be useful
// for circumstances such as keeping track of server-wide byte counts or
// working with custom message types for which the peer does not
// directly provide a callback.
OnRead func(p *Peer, bytesRead int, msg wire.Message, err error)
// OnWrite is invoked when we write a wire message to a peer. It
// consists of the number of bytes written, the message, and whether or
// not an error in the write occurred. This can be useful for
// circumstances such as keeping track of server-wide byte counts.
OnWrite func(p *Peer, bytesWritten int, msg wire.Message, err error)
}
MessageListeners defines callback function pointers to invoke with message listeners for a peer. Any listener which is not set to a concrete callback during peer initialization is ignored. Execution of multiple message listeners occurs serially, so one callback blocks the execution of the next.
NOTE: Unless otherwise documented, these listeners must NOT directly call any blocking calls (such as WaitForShutdown) on the peer instance since the input handler goroutine blocks until the callback has completed. Doing so will result in a deadlock.
type OnVersionCallback ¶
type OnVersionCallback func(*wire.MsgVersion) error
OnVersionCallback is an optional callback function that a caller may provide to receive the remote version message during the handshake process. See Peer.Handshake for details.
type Peer ¶
type Peer struct {
// contains filtered or unexported fields
}
Peer provides a basic concurrent safe Decred peer for handling decred communications via the peer-to-peer protocol. It provides full duplex reading and writing, automatic handling of the initial handshake process, querying of usage statistics and other information about the remote peer such as its address, user agent, and protocol version, output message queuing, inventory trickling, and the ability to dynamically register and unregister callbacks for handling Decred protocol messages.
Outbound messages are typically queued via QueueMessage or QueueInventory. QueueMessage is intended for all messages, including responses to data such as blocks and transactions. QueueInventory, on the other hand, is only intended for relaying inventory as it employs a trickling mechanism to batch the inventory together. However, some helper functions for pushing messages of specific types that typically require common special handling are provided as a convenience.
func NewInboundPeer ¶
NewInboundPeer returns a new inbound Decred peer. Use Peer.Handshake to perform the initial version negotiation and then Peer.Run to begin processing incoming and outgoing messages when the handshake is successful.
func NewOutboundPeer ¶
NewOutboundPeer returns a new outbound Decred peer. Use Peer.Handshake to perform the initial version negotiation and then Peer.Run to begin processing incoming and outgoing messages when the handshake is successful.
func (*Peer) AddKnownInventory ¶
AddKnownInventory adds the passed inventory to the cache of known inventory for the peer.
This function is safe for concurrent access.
func (*Peer) Addr ¶
Addr returns the remote peer address.
This function is safe for concurrent access.
func (*Peer) BytesReceived ¶
BytesReceived returns the total number of bytes received by the peer.
This function is safe for concurrent access.
func (*Peer) BytesSent ¶
BytesSent returns the total number of bytes sent by the peer.
This function is safe for concurrent access.
func (*Peer) Connected ¶
Connected returns whether or not the peer is currently connected.
This function is safe for concurrent access.
func (*Peer) Disconnect ¶
func (p *Peer) Disconnect()
Disconnect disconnects the peer by closing the connection. Calling this function when the peer is already disconnected or in the process of disconnecting will have no effect.
func (*Peer) Handshake ¶
func (p *Peer) Handshake(ctx context.Context, onVersion OnVersionCallback) error
Handshake performs the intitial handshake with a remote peer and returns an error if the handshake does not complete for any reason. It blocks until the handshake successfully completes or an error occurs.
The peer will be disconnected when a non-nil error is returned.
The caller may optionally provide a callback that will be invoked with the version message from the remote peer. Any errors returned from the callback will cause the handshake process to fail and will be returned from this function. Effectively, it provides the caller with an easy mechanism to reject peers based on whatever additional criteria they deem fit.
NOTE: The code in the callback must be careful to avoid using exported methods that reference details that are not yet established. Generally speaking, anything that is set as a result of the information in the version message, with the exception of the negotiated protocol version, must not be relied on.
More specifically, the callback must only rely on the following:
- Anything set in the NewInboundPeer or NewOutboundPeer constructors such as Peer.Addr and Peer.Inbound
- Peer.ProtocolVersion is the negotiated protocol version
- Peer.ID
On the other hand, the callback must NOT rely on any other methods such as:
- Peer.UserAgent (part of the version message)
- Peer.LastBlock (part of the version message)
- Peer.Services (part of the version message)
- Peer.StartingHeight (derived from version message)
- Peer.StatsSnapshot (contains many of the aforementioned details)
No callback for the verack message is provided because a successful handshake guarantees the verack was received. Thus, anything that would be invoked in response to verack, can be done when this function returns without error.
This should only be called once when the peer is first connected.
The caller MUST only start the async I/O processing with Peer.Run after this function returns without error.
func (*Peer) Inbound ¶
Inbound returns whether the peer is inbound.
This function is safe for concurrent access.
func (*Peer) IsKnownInventory ¶
IsKnownInventory returns whether the passed inventory already exists in the known inventory for the peer.
This function is safe for concurrent access.
func (*Peer) LastBlock ¶
LastBlock returns the last block of the peer.
This function is safe for concurrent access.
func (*Peer) LastPingMicros ¶
LastPingMicros returns the last ping micros of the remote peer.
This function is safe for concurrent access.
func (*Peer) LastPingNonce ¶
LastPingNonce returns the last ping nonce of the remote peer.
This function is safe for concurrent access.
func (*Peer) LastPingTime ¶
LastPingTime returns the last ping time of the remote peer.
This function is safe for concurrent access.
func (*Peer) LastRecv ¶
LastRecv returns the last recv time of the peer.
This function is safe for concurrent access.
func (*Peer) LastSend ¶
LastSend returns the last send time of the peer.
This function is safe for concurrent access.
func (*Peer) LocalAddr ¶
LocalAddr returns the local address of the connection or nil if the peer is not currently connected.
This function is safe for concurrent access.
func (*Peer) ProtocolVersion ¶
ProtocolVersion returns the negotiated peer protocol version.
This function is safe for concurrent access.
func (*Peer) PushAddrMsg ¶
func (p *Peer) PushAddrMsg(addresses []*wire.NetAddress) ([]*wire.NetAddress, error)
PushAddrMsg sends an addr message to the connected peer using the provided addresses. This function is useful over manually sending the message via QueueMessage since it automatically limits the addresses to the maximum number allowed by the message and randomizes the chosen addresses when there are too many. It returns the addresses that were actually sent and no message will be sent if there are no entries in the provided addresses slice.
This function is safe for concurrent access.
func (*Peer) PushAddrV2Msg ¶
func (p *Peer) PushAddrV2Msg(addresses []wire.NetAddressV2) []wire.NetAddressV2
PushAddrV2Msg sends an addrv2 message to the connected peer using the provided addresses. This function is useful over manually sending the message via QueueMessage since it automatically limits the addresses to the maximum number allowed by the message and randomizes the chosen addresses when there are too many. It returns the addresses that were actually sent and no message will be sent if there are no entries in the provided addresses slice.
This function is safe for concurrent access.
func (*Peer) PushGetBlocksMsg ¶
PushGetBlocksMsg sends a getblocks message for the provided block locator and stop hash. It will ignore back-to-back duplicate requests.
This function is safe for concurrent access.
func (*Peer) PushGetHeadersMsg ¶
PushGetHeadersMsg sends a getblocks message for the provided block locator and stop hash. It will ignore back-to-back duplicate requests.
This function is safe for concurrent access.
func (*Peer) QueueInventory ¶
QueueInventory adds the passed inventory to the inventory send queue which might not be sent right away, rather it is trickled to the peer in batches. Inventory that the peer is already known to have is ignored.
This function is safe for concurrent access.
func (*Peer) QueueInventoryImmediate ¶
QueueInventoryImmediate adds the passed inventory to the send queue to be sent immediately. This should typically only be used for inventory that is time sensitive such as new tip blocks or votes. Normal inventory should be announced via QueueInventory which instead trickles it to the peer in batches. Inventory that the peer is already known to have is ignored.
This function is safe for concurrent access.
func (*Peer) QueueMessage ¶
QueueMessage adds the passed wire message to the peer send queue.
This function is safe for concurrent access.
func (*Peer) Run ¶
Run begins processing input and output messages. Callers MUST only call this after Peer.Handshake completes without error.
func (*Peer) Services ¶
func (p *Peer) Services() wire.ServiceFlag
Services returns the services flag of the remote peer.
This function is safe for concurrent access.
func (*Peer) StartingHeight ¶
StartingHeight returns the last known height the peer reported during the initial negotiation phase.
This function is safe for concurrent access.
func (*Peer) StatsSnapshot ¶
StatsSnapshot returns a snapshot of the current peer flags and statistics.
This function is safe for concurrent access.
func (*Peer) String ¶
String returns the peer's address and directionality as a human-readable string.
This function is safe for concurrent access.
func (*Peer) TimeConnected ¶
TimeConnected returns the time at which the peer connected.
This function is safe for concurrent access.
func (*Peer) TimeOffset ¶
TimeOffset returns the number of seconds the local time was offset from the time the peer reported during the initial negotiation phase. Negative values indicate the remote peer's time is before the local time.
This function is safe for concurrent access.
func (*Peer) UpdateLastBlockHeight ¶
UpdateLastBlockHeight updates the last known block for the peer.
This function is safe for concurrent access.
func (*Peer) UserAgent ¶
UserAgent returns the user agent of the remote peer.
This function is safe for concurrent access.
func (*Peer) WaitForDisconnect ¶
func (p *Peer) WaitForDisconnect()
WaitForDisconnect waits until the peer has completely disconnected and all resources are cleaned up. This will happen if either the local or remote side has been disconnected or the peer is forcibly disconnected via Disconnect.
func (*Peer) WantsHeaders ¶
WantsHeaders returns if the peer wants header messages instead of inventory vectors for blocks.
This function is safe for concurrent access.
type StatsSnap ¶
type StatsSnap struct {
ID int32
Addr string
Services wire.ServiceFlag
LastSend time.Time
LastRecv time.Time
BytesSent uint64
BytesRecv uint64
ConnTime time.Time
TimeOffset int64
Version uint32
UserAgent string
Inbound bool
StartingHeight int64
LastBlock int64
LastPingNonce uint64
LastPingTime time.Time
LastPingMicros int64
}
StatsSnap is a snapshot of peer stats at a point in time.