id_test.go 4.97 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1
2
3
package identify_test

import (
Jeromy's avatar
Jeromy committed
4
	"context"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
5
6
7
	"testing"
	"time"

Jeromy's avatar
Jeromy committed
8
9
	ic "github.com/libp2p/go-libp2p-crypto"
	peer "github.com/libp2p/go-libp2p-peer"
10
	pstore "github.com/libp2p/go-libp2p-peerstore"
Steven Allen's avatar
Steven Allen committed
11
	swarmt "github.com/libp2p/go-libp2p-swarm/testing"
12
	identify "github.com/libp2p/go-libp2p/p2p/protocol/identify"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
13

Jeromy's avatar
Jeromy committed
14
	blhost "github.com/libp2p/go-libp2p-blankhost"
Jeromy's avatar
Jeromy committed
15
	host "github.com/libp2p/go-libp2p-host"
Jeromy's avatar
Jeromy committed
16
	ma "github.com/multiformats/go-multiaddr"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
17
18
)

19
20
21
func subtestIDService(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
22

Steven Allen's avatar
Steven Allen committed
23
24
	h1 := blhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
	h2 := blhost.NewBlankHost(swarmt.GenSwarm(t, ctx))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
25
26
27
28

	h1p := h1.ID()
	h2p := h2.ID()

Jeromy's avatar
Jeromy committed
29
30
31
	ids1 := identify.NewIDService(h1)
	ids2 := identify.NewIDService(h2)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
32
33
34
	testKnowsAddrs(t, h1, h2p, []ma.Multiaddr{}) // nothing
	testKnowsAddrs(t, h2, h1p, []ma.Multiaddr{}) // nothing

35
36
37
	forgetMe, _ := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/1234")

	h2.Peerstore().AddAddr(h1p, forgetMe, pstore.RecentlyConnectedAddrTTL)
38
	time.Sleep(500 * time.Millisecond)
39

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
40
41
42
43
44
	h2pi := h2.Peerstore().PeerInfo(h2p)
	if err := h1.Connect(ctx, h2pi); err != nil {
		t.Fatal(err)
	}

Jeromy's avatar
Jeromy committed
45
46
47
	h1t2c := h1.Network().ConnsToPeer(h2p)
	if len(h1t2c) == 0 {
		t.Fatal("should have a conn here")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
48
49
	}

Jeromy's avatar
Jeromy committed
50
51
	ids1.IdentifyConn(h1t2c[0])

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
52
53
	// the IDService should be opened automatically, by the network.
	// what we should see now is that both peers know about each others listen addresses.
54
	t.Log("test peer1 has peer2 addrs correctly")
55
	testKnowsAddrs(t, h1, h2p, h2.Peerstore().Addrs(h2p)) // has them
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
56
	testHasProtocolVersions(t, h1, h2p)
57
	testHasPublicKey(t, h1, h2p, h2.Peerstore().PubKey(h2p)) // h1 should have h2's public key
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
58
59
60
61
62
63
64

	// now, this wait we do have to do. it's the wait for the Listening side
	// to be done identifying the connection.
	c := h2.Network().ConnsToPeer(h1.ID())
	if len(c) < 1 {
		t.Fatal("should have connection by now at least.")
	}
Jeromy's avatar
Jeromy committed
65
	ids2.IdentifyConn(c[0])
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
66

67
	addrs := h1.Peerstore().Addrs(h1p)
Steven Allen's avatar
Steven Allen committed
68
	addrs = append(addrs, forgetMe)
69

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
70
	// and the protocol versions.
71
72
	t.Log("test peer2 has peer1 addrs correctly")
	testKnowsAddrs(t, h2, h1p, addrs) // has them
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
73
	testHasProtocolVersions(t, h2, h1p)
74
	testHasPublicKey(t, h2, h1p, h1.Peerstore().PubKey(h1p)) // h1 should have h2's public key
75
76
77
78
79
80
81
82
83
84
85

	// Need both sides to actually notice that the connection has been closed.
	h1.Network().ClosePeer(h2p)
	h2.Network().ClosePeer(h1p)
	if len(h2.Network().ConnsToPeer(h1.ID())) != 0 || len(h1.Network().ConnsToPeer(h2.ID())) != 0 {
		t.Fatal("should have no connections")
	}

	testKnowsAddrs(t, h2, h1p, addrs)
	testKnowsAddrs(t, h1, h2p, h2.Peerstore().Addrs(h2p))

86
	time.Sleep(500 * time.Millisecond)
87
88
89
90

	// Forget the first one.
	testKnowsAddrs(t, h2, h1p, addrs[:len(addrs)-1])

Steven Allen's avatar
Steven Allen committed
91
	time.Sleep(1 * time.Second)
92
93
94
95

	// Forget the rest.
	testKnowsAddrs(t, h1, h2p, []ma.Multiaddr{})
	testKnowsAddrs(t, h2, h1p, []ma.Multiaddr{})
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
96
97
98
}

func testKnowsAddrs(t *testing.T, h host.Host, p peer.ID, expected []ma.Multiaddr) {
99
100
	t.Helper()

101
	actual := h.Peerstore().Addrs(p)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
102
103

	if len(actual) != len(expected) {
104
105
106
		t.Errorf("expected: %s", expected)
		t.Errorf("actual: %s", actual)
		t.Fatal("dont have the same addresses")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
	}

	have := map[string]struct{}{}
	for _, addr := range actual {
		have[addr.String()] = struct{}{}
	}
	for _, addr := range expected {
		if _, found := have[addr.String()]; !found {
			t.Errorf("%s did not have addr for %s: %s", h.ID(), p, addr)
		}
	}
}

func testHasProtocolVersions(t *testing.T, h host.Host, p peer.ID) {
	v, err := h.Peerstore().Get(p, "ProtocolVersion")
	if v == nil {
		t.Error("no protocol version")
		return
	}
Jeromy's avatar
Jeromy committed
126
	if v.(string) != identify.LibP2PVersion {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
127
128
129
130
131
132
133
134
		t.Error("protocol mismatch", err)
	}
	v, err = h.Peerstore().Get(p, "AgentVersion")
	if v.(string) != identify.ClientVersion {
		t.Error("agent version mismatch", err)
	}
}

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
func testHasPublicKey(t *testing.T, h host.Host, p peer.ID, shouldBe ic.PubKey) {
	k := h.Peerstore().PubKey(p)
	if k == nil {
		t.Error("no public key")
		return
	}
	if !k.Equals(shouldBe) {
		t.Error("key mismatch")
		return
	}

	p2, err := peer.IDFromPublicKey(k)
	if err != nil {
		t.Error("could not make key")
	} else if p != p2 {
		t.Error("key does not match peerid")
	}
}

154
// TestIDServiceWait gives the ID service 1s to finish after dialing
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
155
156
// this is becasue it used to be concurrent. Now, Dial wait till the
// id service is done.
157
158
func TestIDService(t *testing.T) {
	oldTTL := pstore.RecentlyConnectedAddrTTL
159
	pstore.RecentlyConnectedAddrTTL = time.Second
160
161
162
	defer func() {
		pstore.RecentlyConnectedAddrTTL = oldTTL
	}()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
163
164
165

	N := 3
	for i := 0; i < N; i++ {
166
		subtestIDService(t)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
167
168
	}
}
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

func TestProtoMatching(t *testing.T) {
	tcp1, _ := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/1234")
	tcp2, _ := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/2345")
	tcp3, _ := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/4567")
	utp, _ := ma.NewMultiaddr("/ip4/1.2.3.4/udp/1234/utp")

	if !identify.HasConsistentTransport(tcp1, []ma.Multiaddr{tcp2, tcp3, utp}) {
		t.Fatal("expected match")
	}

	if identify.HasConsistentTransport(utp, []ma.Multiaddr{tcp2, tcp3}) {
		t.Fatal("expected mismatch")
	}
}