mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 06:42:16 +00:00
P2P docs
This commit is contained in:
parent
bff93107ef
commit
fa7c83166f
100
p2p/README.md
100
p2p/README.md
@ -1,35 +1,77 @@
|
||||
# P2P Module
|
||||
# `tendermint/p2p`
|
||||
|
||||
P2P provides an abstraction around peer-to-peer communication.<br/>
|
||||
Communication happens via Reactors that react to messages from peers.<br/>
|
||||
Each Reactor has one or more Channels of communication for each Peer.<br/>
|
||||
Channels are multiplexed automatically and can be configured.<br/>
|
||||
A Switch is started upon app start, and handles Peer management.<br/>
|
||||
A PEXReactor implementation is provided to automate peer discovery.<br/>
|
||||
`tendermint/p2p` provides an abstraction around peer-to-peer communication.<br/>
|
||||
|
||||
## Channels
|
||||
## Peer/MConnection/Channel
|
||||
|
||||
Each peer connection is multiplexed into channels.
|
||||
The p2p module comes with a channel implementation used for peer
|
||||
discovery (called PEX, short for "peer exchange").
|
||||
Each peer has one `MConnection` (multiplex connection) instance.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><b>Channel</b></td>
|
||||
<td>"PEX"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Messages</b></td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>pexRequestMsg</li>
|
||||
<li>pexResponseMsg</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr />
|
||||
__multiplex__ *noun* a system or signal involving simultaneous transmission of
|
||||
several messages along a single channel of communication.
|
||||
|
||||
## Resources
|
||||
Each `MConnection` handles message transmission on multiple abstract communication
|
||||
`Channel`s. Each channel has a globally unique byte id.
|
||||
The byte id and the relative priorities of each `Channel` are configured upon
|
||||
initialization of the connection.
|
||||
|
||||
* http://www.upnp-hacks.org/upnp.html
|
||||
There are two methods for sending messages:
|
||||
```go
|
||||
func (m MConnection) Send(chId byte, msg interface{}) bool {}
|
||||
func (m MConnection) TrySend(chId byte, msg interface{}) bool {}
|
||||
```
|
||||
|
||||
`Send(chId, msg)` is a blocking call that waits until `msg` is successfully queued
|
||||
for the channel with the given id byte `chId`. The message `msg` is serialized
|
||||
using the `tendermint/binary` submodule's `WriteBinary()` reflection routine.
|
||||
|
||||
`TrySend(chId, msg)` is a nonblocking call that returns false if the channel's
|
||||
queue is full.
|
||||
|
||||
`Send()` and `TrySend()` are also exposed for each `Peer`.
|
||||
|
||||
## Switch/Reactor
|
||||
|
||||
The `Switch` handles peer connections and exposes an API to receive incoming messages
|
||||
on `Reactors`. Each `Reactor` is responsible for handling incoming messages of one
|
||||
or more `Channels`. So while sending outgoing messages is typically performed on the peer,
|
||||
incoming messages are received on the reactor.
|
||||
|
||||
```go
|
||||
// Declare a MyReactor reactor that handles messages on MyChannelId.
|
||||
type MyReactor struct{}
|
||||
|
||||
func (reactor MyReactor) GetChannels() []*ChannelDescriptor {
|
||||
return []*ChannelDescriptor{ChannelDescriptor{Id:MyChannelId, Priority: 1}}
|
||||
}
|
||||
|
||||
func (reactor MyReactor) Receive(chId byte, peer *Peer, msgBytes []byte) {
|
||||
r, n, err := bytes.NewBuffer(msgBytes), new(int64), new(error)
|
||||
msgString := ReadString(r, n, err)
|
||||
fmt.Println(msgString)
|
||||
}
|
||||
|
||||
// Other Reactor methods omitted for brevity
|
||||
...
|
||||
|
||||
switch := NewSwitch([]Reactor{MyReactor{}})
|
||||
|
||||
...
|
||||
|
||||
// Send a random message to all outbound connections
|
||||
for _, peer := range switch.Peers().List() {
|
||||
if peer.IsOutbound() {
|
||||
peer.Send(MyChannelId, "Here's a random message")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### PexReactor/AddrBook
|
||||
|
||||
A `PEXReactor` reactor implementation is provided to automate peer discovery.
|
||||
|
||||
```go
|
||||
book := p2p.NewAddrBook(config.AddrBookFile())
|
||||
pexReactor := p2p.NewPEXReactor(book)
|
||||
...
|
||||
switch := NewSwitch([]Reactor{pexReactor, myReactor, ...})
|
||||
```
|
||||
|
@ -34,8 +34,27 @@ type receiveCbFunc func(chId byte, msgBytes []byte)
|
||||
type errorCbFunc func(interface{})
|
||||
|
||||
/*
|
||||
A MConnection wraps a network connection and handles buffering and multiplexing.
|
||||
<essages are sent with ".Send(channelId, msg)".
|
||||
Each peer has one `MConnection` (multiplex connection) instance.
|
||||
|
||||
__multiplex__ *noun* a system or signal involving simultaneous transmission of
|
||||
several messages along a single channel of communication.
|
||||
|
||||
Each `MConnection` handles message transmission on multiple abstract communication
|
||||
`Channel`s. Each channel has a globally unique byte id.
|
||||
The byte id and the relative priorities of each `Channel` are configured upon
|
||||
initialization of the connection.
|
||||
|
||||
There are two methods for sending messages:
|
||||
func (m MConnection) Send(chId byte, msg interface{}) bool {}
|
||||
func (m MConnection) TrySend(chId byte, msg interface{}) bool {}
|
||||
|
||||
`Send(chId, msg)` is a blocking call that waits until `msg` is successfully queued
|
||||
for the channel with the given id byte `chId`. The message `msg` is serialized
|
||||
using the `tendermint/binary` submodule's `WriteBinary()` reflection routine.
|
||||
|
||||
`TrySend(chId, msg)` is a nonblocking call that returns false if the channel's
|
||||
queue is full.
|
||||
|
||||
Inbound message bytes are handled with an onReceive callback function.
|
||||
*/
|
||||
type MConnection struct {
|
||||
|
@ -10,18 +10,13 @@ import (
|
||||
"github.com/tendermint/tendermint/p2p/upnp"
|
||||
)
|
||||
|
||||
/*
|
||||
Listener is part of a Server.
|
||||
*/
|
||||
type Listener interface {
|
||||
Connections() <-chan net.Conn
|
||||
ExternalAddress() *NetAddress
|
||||
Stop()
|
||||
}
|
||||
|
||||
/*
|
||||
DefaultListener is an implementation of Listener.
|
||||
*/
|
||||
// Implements Listener
|
||||
type DefaultListener struct {
|
||||
listener net.Listener
|
||||
extAddr *NetAddress
|
||||
|
@ -11,8 +11,6 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
/* NetAddress */
|
||||
|
||||
type NetAddress struct {
|
||||
IP net.IP
|
||||
Port uint16
|
||||
|
@ -10,8 +10,6 @@ import (
|
||||
. "github.com/tendermint/tendermint/common"
|
||||
)
|
||||
|
||||
/* Peer */
|
||||
|
||||
type Peer struct {
|
||||
outbound bool
|
||||
mconn *MConnection
|
||||
|
@ -4,9 +4,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
/*
|
||||
IPeerSet has a (immutable) subset of the methods of PeerSet.
|
||||
*/
|
||||
// IPeerSet has a (immutable) subset of the methods of PeerSet.
|
||||
type IPeerSet interface {
|
||||
Has(key string) bool
|
||||
List() []*Peer
|
||||
@ -15,10 +13,8 @@ type IPeerSet interface {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
PeerSet is a special structure for keeping a table of peers.
|
||||
Iteration over the peers is super fast and thread-safe.
|
||||
*/
|
||||
// PeerSet is a special structure for keeping a table of peers.
|
||||
// Iteration over the peers is super fast and thread-safe.
|
||||
type PeerSet struct {
|
||||
mtx sync.Mutex
|
||||
lookup map[string]*peerSetItem
|
||||
|
@ -22,19 +22,10 @@ type Reactor interface {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
All communication amongst peers are multiplexed by "channels".
|
||||
(Not the same as Go "channels")
|
||||
|
||||
To send a message, serialize it into a ByteSlice and send it to each peer.
|
||||
For best performance, re-use the same immutable ByteSlice to each peer.
|
||||
You can also use a TypedBytes{} struct for convenience.
|
||||
You can find all connected and active peers by iterating over ".Peers().List()".
|
||||
".Broadcast()" is provided for convenience, but by iterating over
|
||||
the peers manually the caller can decide which subset receives a message.
|
||||
|
||||
Inbound messages are received by calling ".Receive()".
|
||||
The receiver is responsible for decoding the message bytes, which may be preceded
|
||||
by a single type byte if a TypedBytes{} was used.
|
||||
The `Switch` handles peer connections and exposes an API to receive incoming messages
|
||||
on `Reactors`. Each `Reactor` is responsible for handling incoming messages of one
|
||||
or more `Channels`. So while sending outgoing messages is typically performed on the peer,
|
||||
incoming messages are received on the reactor.
|
||||
*/
|
||||
type Switch struct {
|
||||
reactors []Reactor
|
||||
|
5
p2p/upnp/README.md
Normal file
5
p2p/upnp/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# `tendermint/p2p/upnp`
|
||||
|
||||
## Resources
|
||||
|
||||
* http://www.upnp-hacks.org/upnp.html
|
Loading…
x
Reference in New Issue
Block a user