Browse Source

update spec and addrbook.go

pull/1519/head
Ethan Buchman 7 years ago
parent
commit
3498b676a6
5 changed files with 24 additions and 44 deletions
  1. +1
    -1
      docs/specification/new-spec/p2p/node.md
  2. +11
    -10
      docs/specification/new-spec/p2p/peer.md
  3. +3
    -2
      docs/specification/new-spec/reactors/pex/pex.md
  4. +9
    -22
      p2p/pex/addrbook.go
  5. +0
    -9
      p2p/pex/errors.go

+ 1
- 1
docs/specification/new-spec/p2p/node.md View File

@ -12,7 +12,7 @@ Seeds should operate full nodes with the PEX reactor in a "crawler" mode
that continuously explores to validate the availability of peers.
Seeds should only respond with some top percentile of the best peers it knows about.
See [reputation](TODO) for details on peer quality.
See [the peer-exchange docs](/docs/specification/new-spec/reactors/pex/pex.md)for details on peer quality.
## New Full Node


+ 11
- 10
docs/specification/new-spec/p2p/peer.md View File

@ -2,24 +2,23 @@
This document explains how Tendermint Peers are identified and how they connect to one another.
For details on peer discovery, see the [peer exchange (PEX) reactor doc](pex.md).
For details on peer discovery, see the [peer exchange (PEX) reactor doc](/docs/specification/new-spec/reactors/pex/pex.md).
## Peer Identity
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.PubKey.Address()`, where `Address` uses the scheme defined in go-crypto.
A single peer ID can have multiple IP addresses associated with it.
TODO: define how to deal with this.
A single peer ID can have multiple IP addresses associated with it, but a node
will only ever connect to one at a time.
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,
via authenticated encryption, that it is in possession of the private key
corresponding to `<ID>`. This prevents man-in-the-middle attacks on the peer layer.
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,
for instance via VPN.
If `auth_enc = false`, peers can use an arbitrary ID, but they must always use
one. Authentication can then happen out-of-band of Tendermint, for instance via VPN.
## Connections
@ -84,12 +83,13 @@ The Tendermint Version Handshake allows the peers to exchange their NodeInfo:
```golang
type NodeInfo struct {
ID p2p.ID
Moniker string
Network string
RemoteAddr string
ListenAddr string
Network string
Version string
Channels []int8
Moniker string
Other []string
}
```
@ -98,9 +98,10 @@ The connection is disconnected if:
- `peer.NodeInfo.ID` is not equal `peerConn.ID`
- `peer.NodeInfo.Version` is not formatted as `X.X.X` where X are integers known as Major, Minor, and Revision
- `peer.NodeInfo.Version` Major is not the same as ours
- `peer.NodeInfo.Version` Minor is not the same as ours
- `peer.NodeInfo.Network` is not the same as ours
- `peer.Channels` does not intersect with our known Channels.
- `peer.NodeInfo.ListenAddr` is malformed or is a DNS host that cannot be
resolved
At this point, if we have not disconnected, the peer is valid.


+ 3
- 2
docs/specification/new-spec/reactors/pex/pex.md View File

@ -31,8 +31,9 @@ we try the seeds again.
## Listening
Peers listen on a configurable ListenAddr that they self-report during
handshakes with other peers.
Peers listen on a configurable ListenAddr that they self-report in their
NodeInfo during handshakes with other peers. Peers accept up to (MaxNumPeers -
MinNumOutboundPeers) incoming peers.
## Address Book


+ 9
- 22
p2p/pex/addrbook.go View File

@ -493,11 +493,11 @@ func (a *addrBook) getBucket(bucketType byte, bucketIdx int) map[string]*knownAd
// Adds ka to new bucket. Returns false if it couldn't do it cuz buckets full.
// NOTE: currently it always returns true.
func (a *addrBook) addToNewBucket(ka *knownAddress, bucketIdx int) bool {
func (a *addrBook) addToNewBucket(ka *knownAddress, bucketIdx int) {
// Sanity check
if ka.isOld() {
a.Logger.Error(cmn.Fmt("Cannot add address already in old bucket to a new bucket: %v", ka))
return false
a.Logger.Error("Failed Sanity Check! Cant add old address to new bucket", "ka", knownAddress, "bucket", bucketIdx)
return
}
addrStr := ka.Addr.String()
@ -505,7 +505,7 @@ func (a *addrBook) addToNewBucket(ka *knownAddress, bucketIdx int) bool {
// Already exists?
if _, ok := bucket[addrStr]; ok {
return true
return
}
// Enforce max addresses.
@ -523,8 +523,6 @@ func (a *addrBook) addToNewBucket(ka *knownAddress, bucketIdx int) bool {
// Add it to addrLookup
a.addrLookup[ka.ID()] = ka
return true
}
// Adds ka to old bucket. Returns false if it couldn't do it cuz buckets full.
@ -627,7 +625,6 @@ func (a *addrBook) addAddress(addr, src *p2p.NetAddress) error {
}
ka := a.addrLookup[addr.ID]
if ka != nil {
// Already old.
if ka.isOld() {
@ -647,10 +644,7 @@ func (a *addrBook) addAddress(addr, src *p2p.NetAddress) error {
}
bucket := a.calcNewBucket(addr, src)
added := a.addToNewBucket(ka, bucket)
if !added {
return ErrAddrBookFull{addr, a.size()}
}
a.addToNewBucket(ka, bucket)
return nil
}
@ -696,20 +690,13 @@ func (a *addrBook) moveToOld(ka *knownAddress) {
oldBucketIdx := a.calcOldBucket(ka.Addr)
added := a.addToOldBucket(ka, oldBucketIdx)
if !added {
// No room, must evict something
// No room; move the oldest to a new bucket
oldest := a.pickOldest(bucketTypeOld, oldBucketIdx)
a.removeFromBucket(oldest, bucketTypeOld, oldBucketIdx)
// Find new bucket to put oldest in
newBucketIdx := a.calcNewBucket(oldest.Addr, oldest.Src)
added := a.addToNewBucket(oldest, newBucketIdx)
// No space in newBucket either, just put it in freedBucket from above.
if !added {
added := a.addToNewBucket(oldest, freedBucket)
if !added {
a.Logger.Error(cmn.Fmt("Could not migrate oldest %v to freedBucket %v", oldest, freedBucket))
}
}
// Finally, add to bucket again.
a.addToNewBucket(oldest, newBucketIdx)
// Finally, add our ka to old bucket again.
added = a.addToOldBucket(ka, oldBucketIdx)
if !added {
a.Logger.Error(cmn.Fmt("Could not re-add ka %v to oldBucketIdx %v", ka, oldBucketIdx))


+ 0
- 9
p2p/pex/errors.go View File

@ -30,12 +30,3 @@ type ErrAddrBookNilAddr struct {
func (err ErrAddrBookNilAddr) Error() string {
return fmt.Sprintf("Cannot add a nil address. Got (addr, src) = (%v, %v)", err.Addr, err.Src)
}
type ErrAddrBookFull struct {
Addr *p2p.NetAddress
Size int
}
func (err ErrAddrBookFull) Error() string {
return fmt.Sprintf("Can't add new address (%v), addr book is full (%d)", err.Addr, err.Size)
}

Loading…
Cancel
Save