diff --git a/p2p/README.md b/p2p/README.md index bf0a5c4d0..d653b2caf 100644 --- a/p2p/README.md +++ b/p2p/README.md @@ -4,9 +4,9 @@ `tendermint/tendermint/p2p` provides an abstraction around peer-to-peer communication.
-## Peer/MConnection/Channel +## MConnection -Each peer has one `MConnection` (multiplex connection) instance. +`MConnection` is a multiplex connection: __multiplex__ *noun* a system or signal involving simultaneous transmission of several messages along a single channel of communication. @@ -16,6 +16,43 @@ Each `MConnection` handles message transmission on multiple abstract communicati The byte id and the relative priorities of each `Channel` are configured upon initialization of the connection. +The `MConnection` supports three packet types: Ping, Pong, and Msg. + +### Ping and Pong + +The ping and pong messages consist of writing a single byte to the connection; 0x1 and 0x2, respectively + +When we haven't received any messages on an `MConnection` in a time `pingTimeout`, we send a ping message. +When a ping is received on the `MConnection`, a pong is sent in response. + +If a pong is not received in sufficient time, the peer's score should be decremented (TODO). + +### Msg + +Messages in channels are chopped into smaller msgPackets for multiplexing. + +``` +type msgPacket struct { + ChannelID byte + EOF byte // 1 means message ends here. + Bytes []byte +} +``` + +The msgPacket is serialized using go-wire, and prefixed with a 0x3. +The received `Bytes` of a sequential set of packets are appended together +until a packet with `EOF=1` is received, at which point the complete serialized message +is returned for processing by the corresponding channels `onReceive` function. + +### Multiplexing + +Messages are sent from a single `sendRoutine`, which loops over a select statement that results in the sending +of a ping, a pong, or a batch of data messages. The batch of data messages may include messages from multiple channels. +Message bytes are queued for sending in their respective channel, with each channel holding one unsent message at a time. +Messages are chosen for a batch one a time from the channel with the lowest ratio of recently sent bytes to channel priority. + +## Sending Messages + There are two methods for sending messages: ```go func (m MConnection) Send(chID byte, msg interface{}) bool {} @@ -31,6 +68,12 @@ queue is full. `Send()` and `TrySend()` are also exposed for each `Peer`. +## Peer + +Each peer has one `MConnection` instance, and includes other information such as whether the connection +was outbound, whether the connection should be recreated if it closes, various identity information about the node, +and other higher level thread-safe data used by the reactors. + ## Switch/Reactor The `Switch` handles peer connections and exposes an API to receive incoming messages diff --git a/p2p/pex_reactor.go b/p2p/pex_reactor.go index 54c2d06b5..2f13703ef 100644 --- a/p2p/pex_reactor.go +++ b/p2p/pex_reactor.go @@ -143,7 +143,7 @@ func (r *PEXReactor) Receive(chID byte, src Peer, msgBytes []byte) { r.SendAddrs(src, r.book.GetSelection()) case *pexAddrsMessage: // We received some peer addresses from src. - // (We don't want to get spammed with bad peers) + // TODO: (We don't want to get spammed with bad peers) for _, addr := range msg.Addrs { if addr != nil { r.book.AddAddress(addr, srcAddr) diff --git a/p2p/switch.go b/p2p/switch.go index af9324a9b..994a3344d 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -481,17 +481,6 @@ func (sw *Switch) listenerRoutine(l Listener) { // cleanup } -//----------------------------------------------------------------------------- - -type SwitchEventNewPeer struct { - Peer Peer -} - -type SwitchEventDonePeer struct { - Peer Peer - Error interface{} -} - //------------------------------------------------------------------ // Connects switches via arbitrary net.Conn. Used for testing.