p2p: always advertise self, to enable mutual address discovery (#7594)

Fixes #7593
This commit is contained in:
Gui
2022-01-19 22:39:59 +01:00
committed by GitHub
parent c8e8a62084
commit ebbc3f02f5
4 changed files with 35 additions and 0 deletions

View File

@@ -25,6 +25,7 @@ Special thanks to external contributors on this release:
- [p2p] \#7035 Remove legacy P2P routing implementation and associated configuration options. (@tychoish)
- [p2p] \#7265 Peer manager reduces peer score for each failed dial attempts for peers that have not successfully dialed. (@tychoish)
- [p2p] [\#7594](https://github.com/tendermint/tendermint/pull/7594) always advertise self, to enable mutual address discovery. (@altergui)
- Go API

View File

@@ -136,6 +136,10 @@ type PeerManagerOptions struct {
// consider private and never gossip.
PrivatePeers map[types.NodeID]struct{}
// SelfAddress is the address that will be advertised to peers for them to dial back to us.
// If Hostname and Port are unset, Advertise() will include no self-announcement
SelfAddress NodeAddress
// persistentPeers provides fast PersistentPeers lookups. It is built
// by optimize().
persistentPeers map[types.NodeID]bool
@@ -791,6 +795,13 @@ func (m *PeerManager) Advertise(peerID types.NodeID, limit uint16) []NodeAddress
defer m.mtx.Unlock()
addresses := make([]NodeAddress, 0, limit)
// advertise ourselves, to let everyone know how to dial us back
// and enable mutual address discovery
if m.options.SelfAddress.Hostname != "" && m.options.SelfAddress.Port != 0 {
addresses = append(addresses, m.options.SelfAddress)
}
for _, peer := range m.store.Ranked() {
if peer.ID == peerID {
continue

View File

@@ -1828,6 +1828,23 @@ func TestPeerManager_Advertise(t *testing.T) {
}, peerManager.Advertise(dID, 2))
}
func TestPeerManager_Advertise_Self(t *testing.T) {
dID := types.NodeID(strings.Repeat("d", 40))
self := p2p.NodeAddress{Protocol: "tcp", NodeID: selfID, Hostname: "2001:db8::1", Port: 26657}
// Create a peer manager with SelfAddress defined.
peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{
SelfAddress: self,
})
require.NoError(t, err)
// peer manager should always advertise its SelfAddress.
require.ElementsMatch(t, []p2p.NodeAddress{
self,
}, peerManager.Advertise(dID, 100))
}
func TestPeerManager_SetHeight_GetHeight(t *testing.T) {
a := p2p.NodeAddress{Protocol: "memory", NodeID: types.NodeID(strings.Repeat("a", 40))}
b := p2p.NodeAddress{Protocol: "memory", NodeID: types.NodeID(strings.Repeat("b", 40))}

View File

@@ -305,6 +305,11 @@ func createPeerManager(
nodeID types.NodeID,
) (*p2p.PeerManager, closer, error) {
selfAddr, err := p2p.ParseNodeAddress(nodeID.AddressString(cfg.P2P.ExternalAddress))
if err != nil {
return nil, func() error { return nil }, fmt.Errorf("couldn't parse ExternalAddress %q: %w", cfg.P2P.ExternalAddress, err)
}
privatePeerIDs := make(map[types.NodeID]struct{})
for _, id := range tmstrings.SplitAndTrimEmpty(cfg.P2P.PrivatePeerIDs, ",", " ") {
privatePeerIDs[types.NodeID(id)] = struct{}{}
@@ -320,6 +325,7 @@ func createPeerManager(
}
options := p2p.PeerManagerOptions{
SelfAddress: selfAddr,
MaxConnected: maxConns,
MaxConnectedUpgrade: 4,
MaxPeers: 1000,