Merge branch 'develop' into 1087-update-docker

This commit is contained in:
Anton Kaliaev 2018-01-09 12:21:23 -06:00 committed by GitHub
commit b8214fce66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 47 deletions

View File

@ -6,14 +6,14 @@ Here we describe configuration options around the Peer Exchange.
`--p2p.seed_mode` `--p2p.seed_mode`
The node operates in seed mode. It will kick incoming peers after sharing some peers. The node operates in seed mode. In seed mode, a node continuously crawls the network for peers,
It will continually crawl the network for peers. and upon incoming connection shares some peers and disconnects.
## Seeds ## Seeds
`--p2p.seeds “1.2.3.4:466656,2.3.4.5:4444”` `--p2p.seeds “1.2.3.4:466656,2.3.4.5:4444”`
Dials these seeds when we need more peers. They will return a list of peers and then disconnect. Dials these seeds when we need more peers. They should return a list of peers and then disconnect.
If we already have enough peers in the address book, we may never need to dial them. If we already have enough peers in the address book, we may never need to dial them.
## Persistent Peers ## Persistent Peers
@ -27,7 +27,7 @@ anchor us in the p2p network.
Note that the auto-redial uses exponential backoff and will give up Note that the auto-redial uses exponential backoff and will give up
after a day of trying to connect. after a day of trying to connect.
NOTE: If `dial_seeds` and `persistent_peers` intersect, NOTE: If `seeds` and `persistent_peers` intersect,
the user will be WARNED that seeds may auto-close connections the user will be WARNED that seeds may auto-close connections
and the node may not be able to keep the connection persistent. and the node may not be able to keep the connection persistent.

View File

@ -1,12 +1,14 @@
## P2P Multiplex Connection
...
## MConnection ## MConnection
`MConnection` is a multiplex connection: `MConnection` is a multiplex connection that supports multiple independent streams
with distinct quality of service guarantees atop a single TCP connection.
__multiplex__ *noun* a system or signal involving simultaneous transmission of Each stream is known as a `Channel` and each `Channel` has a globally unique byte id.
several messages along a single channel of communication. Each `Channel` also has a relative priority that determines the quality of service
of the `Channel` in comparison to the others.
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 The byte id and the relative priorities of each `Channel` are configured upon
initialization of the connection. initialization of the connection.
@ -14,12 +16,13 @@ The `MConnection` supports three packet types: Ping, Pong, and Msg.
### Ping and Pong ### Ping and Pong
The ping and pong messages consist of writing a single byte to the connection; 0x1 and 0x2, respectively 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 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. When a ping is received on the `MConnection`, a pong is sent in response only if there are no other messages
to send and the peer has not sent us too many pings.
If a pong is not received in sufficient time, the peer's score should be decremented (TODO). If a pong or message is not received in sufficient time after a ping, disconnect from the peer.
### Msg ### Msg
@ -57,8 +60,8 @@ func (m MConnection) TrySend(chID byte, msg interface{}) bool {}
for the channel with the given id byte `chID`. The message `msg` is serialized for the channel with the given id byte `chID`. The message `msg` is serialized
using the `tendermint/wire` submodule's `WriteBinary()` reflection routine. using the `tendermint/wire` submodule's `WriteBinary()` reflection routine.
`TrySend(chID, msg)` is a nonblocking call that returns false if the channel's `TrySend(chID, msg)` is a nonblocking call that queues the message msg in the channel
queue is full. with the given id byte chID if the queue is not full; otherwise it returns false immediately.
`Send()` and `TrySend()` are also exposed for each `Peer`. `Send()` and `TrySend()` are also exposed for each `Peer`.
@ -103,14 +106,3 @@ for _, peer := range switch.Peers().List() {
} }
} }
``` ```
### PexReactor/AddrBook
A `PEXReactor` reactor implementation is provided to automate peer discovery.
```go
book := p2p.NewAddrBook(addrBookFilePath)
pexReactor := p2p.NewPEXReactor(book)
...
switch := NewSwitch([]Reactor{pexReactor, myReactor, ...})
```

View File

@ -39,8 +39,10 @@ A node checks its address book on startup and attempts to connect to peers from
If it can't connect to any peers after some time, it falls back to the seeds to find more. If it can't connect to any peers after some time, it falls back to the seeds to find more.
Restarted full nodes can run the `blockchain` or `consensus` reactor protocols to sync up Restarted full nodes can run the `blockchain` or `consensus` reactor protocols to sync up
to the latest state of the blockchain, assuming they aren't too far behind. to the latest state of the blockchain from wherever they were last.
If they are too far behind, they may need to validate a recent `H` and `HASH` out-of-band again. In a Proof-of-Stake context, if they are sufficiently far behind (greater than the length
of the unbonding period), they will need to validate a recent `H` and `HASH` out-of-band again
so they know they have synced the correct chain.
## Validator Node ## Validator Node
@ -54,6 +56,7 @@ Validators that know and trust each other can accept incoming connections from o
## Sentry Node ## Sentry Node
Sentry nodes are guardians of a validator node and provide it access to the rest of the network. Sentry nodes are guardians of a validator node and provide it access to the rest of the network.
They should be well connected to other full nodes on the network.
Sentry nodes may be dynamic, but should maintain persistent connections to some evolving random subset of each other. Sentry nodes may be dynamic, but should maintain persistent connections to some evolving random subset of each other.
They should always expect to have direct incoming connections from the validator node and its backup/s. They should always expect to have direct incoming connections from the validator node and its backup/s.
They do not report the validator node's address in the PEX. They do not report the validator node's address in the PEX.

View File

@ -5,15 +5,11 @@ and how other peers are found.
## Peer Identity ## Peer Identity
Tendermint peers are expected to maintain long-term persistent identities in the form of a private key. Tendermint peers are expected to maintain long-term persistent identities in the form of a public key.
Each peer has an ID defined as `peer.ID == peer.PrivKey.Address()`, where `Address` uses the scheme defined in go-crypto. Each peer has an ID defined as `peer.ID == peer.PubKey.Address()`, where `Address` uses the scheme defined in go-crypto.
Peer ID's must come with some Proof-of-Work; that is,
they must satisfy `peer.PrivKey.Address() < target` for some difficulty target.
This ensures they are not too easy to generate. To begin, let `target == 2^240`.
A single peer ID can have multiple IP addresses associated with it. A single peer ID can have multiple IP addresses associated with it.
For simplicity, we only keep track of the latest one. TODO: define how to deal with this.
When attempting to connect to a peer, we use the PeerURL: `<ID>@<IP>:<PORT>`. When attempting to connect to a peer, we use the PeerURL: `<ID>@<IP>:<PORT>`.
We will attempt to connect to the peer at IP:PORT, and verify, We will attempt to connect to the peer at IP:PORT, and verify,
@ -22,7 +18,7 @@ corresponding to `<ID>`. This prevents man-in-the-middle attacks on the peer lay
Peers can also be connected to without specifying an ID, ie. just `<IP>:<PORT>`. Peers can also be connected to without specifying an ID, ie. just `<IP>:<PORT>`.
In this case, the peer must be authenticated out-of-band of Tendermint, In this case, the peer must be authenticated out-of-band of Tendermint,
for instance via VPN for instance via VPN.
## Connections ## Connections
@ -49,8 +45,8 @@ It goes as follows:
- if we had the smaller ephemeral pubkey, use nonce1 for receiving, nonce2 for sending; - if we had the smaller ephemeral pubkey, use nonce1 for receiving, nonce2 for sending;
else the opposite else the opposite
- all communications from now on are encrypted using the shared secret and the nonces, where each nonce - all communications from now on are encrypted using the shared secret and the nonces, where each nonce
- we now have an encrypted channel, but still need to authenticate
increments by 2 every time it is used increments by 2 every time it is used
- we now have an encrypted channel, but still need to authenticate
- generate a common challenge to sign: - generate a common challenge to sign:
- SHA256 of the sorted (lowest first) and concatenated ephemeral pub keys - SHA256 of the sorted (lowest first) and concatenated ephemeral pub keys
- sign the common challenge with our persistent private key - sign the common challenge with our persistent private key
@ -76,7 +72,7 @@ an existing peer. If so, we disconnect.
We also check the peer's address and public key against We also check the peer's address and public key against
an optional whitelist which can be managed through the ABCI app - an optional whitelist which can be managed through the ABCI app -
if the whitelist is enabled and the peer does not qualigy, the connection is if the whitelist is enabled and the peer does not qualify, the connection is
terminated. terminated.
@ -86,14 +82,14 @@ The Tendermint Version Handshake allows the peers to exchange their NodeInfo:
``` ```
type NodeInfo struct { type NodeInfo struct {
PubKey crypto.PubKey `json:"pub_key"` PubKey crypto.PubKey
Moniker string `json:"moniker"` Moniker string
Network string `json:"network"` Network string
RemoteAddr string `json:"remote_addr"` RemoteAddr string
ListenAddr string `json:"listen_addr"` // accepting in ListenAddr string
Version string `json:"version"` // major.minor.revision Version string
Channels []int8 `json:"channels"` // active reactor channels Channels []int8
Other []string `json:"other"` // other application specific data Other []string
} }
``` ```