holepunch-hop 0.4.4 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +3 -0
- package/package.json +11 -5
- package/src/index.js +45 -10
- package/src/{peers.js → network/peers.js} +507 -138
- package/src/{bees.js → storage/bees.js} +47 -37
- package/src/{drive.js → storage/drive.js} +2 -3
- package/src/{fileParser.js → storage/fileParser.js} +1 -1
- package/test/datacommands/files/data/jan3-bitcoin.csv +17 -0
- package/test/datacommands/files/large-csv.test.js +7 -0
- package/test/datacommands/files/small-csv.test.js +76 -0
- package/test/datacommands/ledger/save-get-ledger.test.js +117 -0
- package/test/datacommands/results/save-get-results.test.js +122 -0
- package/test/holepunch-initiate.test.js +47 -0
- package/test/multipers/ten-peers-network.test.js +437 -0
- package/test/setup-bee-holepunch.test.js +45 -0
- package/test/setup-holepunch.test.js +14 -13
- package/test/threepers/peer3-geninvite-after.test.js +439 -0
- package/test/threepers/three-peers.test.js +159 -0
- package/test/threepers/two-then-three.test.js +434 -0
- package/test/twopeers/peerClient-Server.test.js +243 -0
- package/test/twopeers/reconnect-peers.test.js +257 -0
- package/test/twopeers/reconnect-serverthen-conerr.test.js +304 -0
- package/test/twopeers/reconnect-then-conerr.test.js +309 -0
- package/test/twopeers/two-peer-one-disconnect.test.js +162 -0
- package/test/twopeers/two-peer-server-disconnect.test.js +167 -0
- package/vitest.config.js +8 -0
- /package/src/{kbledger.js → ledger/kbledger.js} +0 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
2
|
+
import Hyperswarm from 'hyperswarm'
|
|
3
|
+
import NetworkPeers from '../../src/network/peers.js'
|
|
4
|
+
import crypto from 'crypto'
|
|
5
|
+
|
|
6
|
+
describe('Three Peer Connection Tests', () => {
|
|
7
|
+
let peer1
|
|
8
|
+
let peer2
|
|
9
|
+
let peer3
|
|
10
|
+
let swarm1
|
|
11
|
+
let swarm2
|
|
12
|
+
let swarm3
|
|
13
|
+
let testConfig
|
|
14
|
+
let savedPeerNetworkClient = []
|
|
15
|
+
let savedPeerNetworkServer = []
|
|
16
|
+
let topicReconnect = ''
|
|
17
|
+
let topicReconnect13 = ''
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const randomString = crypto.randomBytes(32).toString('hex')
|
|
21
|
+
topicReconnect = randomString
|
|
22
|
+
console.log(topicReconnect)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
const randomString13 = crypto.randomBytes(32).toString('hex')
|
|
27
|
+
topicReconnect13 = randomString13
|
|
28
|
+
console.log(topicReconnect13)
|
|
29
|
+
|
|
30
|
+
beforeEach(async () => {
|
|
31
|
+
// Create swarms for each peer
|
|
32
|
+
swarm1 = new Hyperswarm()
|
|
33
|
+
swarm2 = new Hyperswarm()
|
|
34
|
+
swarm3 = new Hyperswarm()
|
|
35
|
+
|
|
36
|
+
// Create peer instances
|
|
37
|
+
peer1 = new NetworkPeers({}, swarm1)
|
|
38
|
+
peer2 = new NetworkPeers({}, swarm2)
|
|
39
|
+
peer3 = new NetworkPeers({}, swarm3)
|
|
40
|
+
|
|
41
|
+
console.log('TTpppppppppppppppppppp---PUBKEY owner---pppppppp')
|
|
42
|
+
console.log(peer1.swarm.keyPair.publicKey.toString('hex'))
|
|
43
|
+
console.log(peer2.swarm.keyPair.publicKey.toString('hex'))
|
|
44
|
+
console.log(peer3.swarm.keyPair.publicKey.toString('hex'))
|
|
45
|
+
|
|
46
|
+
testConfig = {
|
|
47
|
+
peer1to2: {
|
|
48
|
+
peer1: {
|
|
49
|
+
publicKey: peer1.swarm.keyPair.publicKey.toString('hex'),
|
|
50
|
+
client: false
|
|
51
|
+
},
|
|
52
|
+
peer2: {
|
|
53
|
+
publicKey: peer2.swarm.keyPair.publicKey.toString('hex'),
|
|
54
|
+
client: true
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
peer1to3: {
|
|
58
|
+
peer1: {
|
|
59
|
+
publicKey: peer1.swarm.keyPair.publicKey.toString('hex'),
|
|
60
|
+
client: false
|
|
61
|
+
},
|
|
62
|
+
peer3: {
|
|
63
|
+
publicKey: peer3.swarm.keyPair.publicKey.toString('hex'),
|
|
64
|
+
client: true
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
peer2to3: {
|
|
68
|
+
peer2: {
|
|
69
|
+
publicKey: peer2.swarm.keyPair.publicKey.toString('hex'),
|
|
70
|
+
client: false
|
|
71
|
+
},
|
|
72
|
+
peer3: {
|
|
73
|
+
publicKey: peer3.swarm.keyPair.publicKey.toString('hex'),
|
|
74
|
+
client: true
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
}, 20000)
|
|
81
|
+
|
|
82
|
+
afterEach(async () => {
|
|
83
|
+
console.log('TTCleaning up test environment')
|
|
84
|
+
await Promise.all([
|
|
85
|
+
swarm1.destroy(),
|
|
86
|
+
swarm2.destroy(),
|
|
87
|
+
swarm3.destroy()
|
|
88
|
+
])
|
|
89
|
+
peer1 = null
|
|
90
|
+
peer2 = null
|
|
91
|
+
peer3 = null
|
|
92
|
+
}, 10000)
|
|
93
|
+
|
|
94
|
+
describe('Basic Connection', () => {
|
|
95
|
+
it('should establish start connections peer one to peer two', async () => {
|
|
96
|
+
let countConnect = 0
|
|
97
|
+
// Set up peer1 as the initial listener
|
|
98
|
+
peer1.peerJoinClient()
|
|
99
|
+
peer2.peerJoinClient()
|
|
100
|
+
|
|
101
|
+
let logicPrepserverStatus = async function (holePunch, info, publicKey) {
|
|
102
|
+
return await holePunch.prepareConnectionInfo(info, publicKey)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Set up peer2 and peer3 with mock peer data
|
|
106
|
+
const mockPeer1 = {
|
|
107
|
+
publickey: peer1.swarm.keyPair.publicKey.toString('hex'),
|
|
108
|
+
live: false,
|
|
109
|
+
value: {
|
|
110
|
+
live: false,
|
|
111
|
+
key: peer1.swarm.keyPair.publicKey.toString('hex')
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
peer2.peerJoin(mockPeer1)
|
|
115
|
+
|
|
116
|
+
// Create connection promises for each peer
|
|
117
|
+
const connectionPromises = [
|
|
118
|
+
/* PEER 1 FIRST */
|
|
119
|
+
new Promise((resolve) => {
|
|
120
|
+
peer1.swarm.on('connection', (conn, info) => {
|
|
121
|
+
console.log('TTPeer1 FIRST connection:')
|
|
122
|
+
// console.log(conn)
|
|
123
|
+
// console.log(info.topics)
|
|
124
|
+
// console.log(info.publicKey.toString('hex'))
|
|
125
|
+
// console.log(peer1.swarm.peers)
|
|
126
|
+
countConnect++
|
|
127
|
+
//expect(info.publicKey).toBeDefined()
|
|
128
|
+
//expect(info.client).toBe(testConfig.peer1to2.peer1.client)
|
|
129
|
+
|
|
130
|
+
const publicKeyPeer1 = info.publicKey.toString('hex')
|
|
131
|
+
let logicInfo = logicPrepserverStatus(peer1, info, publicKeyPeer1)
|
|
132
|
+
|
|
133
|
+
if (info.client === testConfig.peer1to2.peer1.client) { // peer1 is server
|
|
134
|
+
console.log('TT peer1 logic assertions')
|
|
135
|
+
// expect(logicInfo.serverStatus).toBe(true)
|
|
136
|
+
// expect(logicInfo.topicKeylive.length).toBe(0)
|
|
137
|
+
// expect(logicInfo.discoveryTopicInfo.firstTime).toBe(true)
|
|
138
|
+
} else {
|
|
139
|
+
// Either serverStatus is true or there's a topic set
|
|
140
|
+
expect(logicInfo.serverStatus || logicInfo.topicKeylive.length > 0).toBe(true)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
// Save the peer network data for reconnection
|
|
145
|
+
// Store connection for verification
|
|
146
|
+
const publicKeyHex = info.publicKey.toString('hex')
|
|
147
|
+
savedPeerNetworkClient.push({
|
|
148
|
+
key: publicKeyHex,
|
|
149
|
+
value: {
|
|
150
|
+
name: 'peer2',
|
|
151
|
+
publickey: publicKeyHex,
|
|
152
|
+
roletaken: true,
|
|
153
|
+
longterm: true,
|
|
154
|
+
settopic: true,
|
|
155
|
+
topic: topicReconnect,
|
|
156
|
+
live: false,
|
|
157
|
+
livePeerkey: ''
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
// process network message
|
|
161
|
+
conn.on('data', data =>
|
|
162
|
+
// assess data
|
|
163
|
+
peer1.assessData(publicKeyHex, data)
|
|
164
|
+
)
|
|
165
|
+
if (countConnect === 2) {
|
|
166
|
+
console.log('TTnow resolve')
|
|
167
|
+
resolve()
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
}),
|
|
171
|
+
/* PEER 2 FIRST */
|
|
172
|
+
new Promise((resolve) => {
|
|
173
|
+
peer2.swarm.on('connection', (conn, info) => {
|
|
174
|
+
console.log('TT Peer2 FIRST connection:')
|
|
175
|
+
// console.log(conn)
|
|
176
|
+
// console.log(info.topics)
|
|
177
|
+
// console.log(peer2.swarm.peers)
|
|
178
|
+
countConnect++
|
|
179
|
+
// expect(info.publicKey).toBeDefined()
|
|
180
|
+
// Peer2's role depends on which peer it's connecting to
|
|
181
|
+
if (info.publicKey === testConfig.peer1to2.peer1.publicKey) {
|
|
182
|
+
// expect(info.client).toBe(testConfig.peer1to2.peer2.client) // Peer2 is client to Peer1
|
|
183
|
+
}
|
|
184
|
+
// Store connection for verification on reconnect
|
|
185
|
+
const publicKeyHex2 = info.publicKey.toString('hex')
|
|
186
|
+
let logicInfo = logicPrepserverStatus(peer1, info, publicKeyHex2)
|
|
187
|
+
if (info.client === testConfig.peer1to2.peer2.client) { // peer2 is client
|
|
188
|
+
console.log('TTpeer2 assertion logic')
|
|
189
|
+
// expect(logicInfo.serverStatus).toBe(false)
|
|
190
|
+
// xpect(logicInfo.topicKeylive.length).toBe(0)
|
|
191
|
+
// expect(logicInfo.discoveryTopicInfo.firstTime).toBe(true)
|
|
192
|
+
} else {
|
|
193
|
+
// Either serverStatus is true or there's a topic set
|
|
194
|
+
expect(logicInfo.serverStatus || logicInfo.topicKeylive.length > 0).toBe(true)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
savedPeerNetworkServer.push({
|
|
198
|
+
key: publicKeyHex2,
|
|
199
|
+
value: {
|
|
200
|
+
name: 'peer1',
|
|
201
|
+
publickey: publicKeyHex2,
|
|
202
|
+
roletaken: false,
|
|
203
|
+
longterm: true,
|
|
204
|
+
settopic: false,
|
|
205
|
+
topic: topicReconnect,
|
|
206
|
+
live: false,
|
|
207
|
+
livePeerkey: ''
|
|
208
|
+
}
|
|
209
|
+
})
|
|
210
|
+
// process network message
|
|
211
|
+
conn.on('data', data =>
|
|
212
|
+
// assess data
|
|
213
|
+
peer2.assessData(publicKeyHex2, data)
|
|
214
|
+
)
|
|
215
|
+
if (countConnect === 1) {
|
|
216
|
+
console.log('TTresolve two')
|
|
217
|
+
resolve()
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
// Wait for all connections to be established
|
|
224
|
+
await Promise.all(connectionPromises)
|
|
225
|
+
|
|
226
|
+
// Add timeout to prevent hanging
|
|
227
|
+
const timeout = setTimeout(() => {
|
|
228
|
+
throw new Error('Connection did not establish within timeout period')
|
|
229
|
+
}, 2000)
|
|
230
|
+
|
|
231
|
+
// Clear timeout if connection was successful
|
|
232
|
+
clearTimeout(timeout)
|
|
233
|
+
}, 20000) // 50 second timeout
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
/* reconnection TEST from here */
|
|
240
|
+
describe('reconnection using saved data', () => {
|
|
241
|
+
it('should use saved relationship data for reconnection but peer1 to peer2 first time should go through first time path logic', async () => {
|
|
242
|
+
console.log('TTreconnection using saved data')
|
|
243
|
+
// keep track count connection to closetest
|
|
244
|
+
let connectionCount = 0
|
|
245
|
+
let peer1Count = 0
|
|
246
|
+
// Set up peer1 as the initial listener
|
|
247
|
+
peer1.peerJoinClient()
|
|
248
|
+
peer2.peerJoinClient()
|
|
249
|
+
|
|
250
|
+
let logicPrepserverStatus = async function (holePunch, info, publicKey) {
|
|
251
|
+
return await holePunch.prepareConnectionInfo(info, publicKey)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Create connection promise to verify reconnection details
|
|
255
|
+
let reconnectionPromise = new Promise(async (resolve) => {
|
|
256
|
+
|
|
257
|
+
// Reconnect using saved peer network data
|
|
258
|
+
peer1.setupConnectionBegin(savedPeerNetworkClient)
|
|
259
|
+
// Add 3 second delay before starting serverPeer
|
|
260
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
261
|
+
peer2.setupConnectionBegin(savedPeerNetworkServer)
|
|
262
|
+
|
|
263
|
+
peer1.swarm.on('connection', async (conn, info) => {
|
|
264
|
+
console.log('TT Peer1 RECON connection details:')
|
|
265
|
+
// console.log(peer1.swarm.status(topicReconnect))
|
|
266
|
+
connectionCount++
|
|
267
|
+
peer1Count++
|
|
268
|
+
let test2complete = false
|
|
269
|
+
// Store connection for verification
|
|
270
|
+
const publicKeyHex = info.publicKey.toString('hex')
|
|
271
|
+
// to differenciate between peer 2 and peer3
|
|
272
|
+
if (peer1Count === 1) {
|
|
273
|
+
console.log('TT peer one RECON batch assert 111111')
|
|
274
|
+
// check logic
|
|
275
|
+
let logicInfo = await logicPrepserverStatus(peer1, info, publicKeyHex)
|
|
276
|
+
if (info.client === testConfig.peer1to2.peer1.client) { // peer1 is server
|
|
277
|
+
expect(logicInfo.discoveryTopicInfo.firstTime).toBe('wait-topic-confirm')
|
|
278
|
+
} else {
|
|
279
|
+
// Either serverStatus is true or there's a topic set
|
|
280
|
+
|
|
281
|
+
}
|
|
282
|
+
} else if (peer1Count === 2) {
|
|
283
|
+
console.log('TT peer one RECON batch assert 222222')
|
|
284
|
+
// check logic
|
|
285
|
+
let logicInfo = await logicPrepserverStatus(peer1, info, publicKeyHex)
|
|
286
|
+
// For peer1 (server) - first-time connection
|
|
287
|
+
if (info.client === false) { // peer1 is server
|
|
288
|
+
console.log('TT server asserts peer1 to peer3 first time but with peer2 already connected')
|
|
289
|
+
expect(logicInfo.discoveryTopicInfo.firstTime).toBe('wait-topic-confirm')
|
|
290
|
+
test2complete = true
|
|
291
|
+
console.log('test2222 over')
|
|
292
|
+
// resolve()
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
// Either serverStatus is true or there's a topic set
|
|
296
|
+
|
|
297
|
+
}
|
|
298
|
+
} else {
|
|
299
|
+
console.log('no match to peer 2 or 3 XXXXXXXX')
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// process network message
|
|
303
|
+
conn.on('data', data =>
|
|
304
|
+
// assess data
|
|
305
|
+
peer1.assessData(publicKeyHex, data)
|
|
306
|
+
)
|
|
307
|
+
// Resolve when reconnection is established
|
|
308
|
+
if (connectionCount === 4 && test2complete === true) {
|
|
309
|
+
console.log('TT resolve peerone')
|
|
310
|
+
resolve()
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
peer2.swarm.on('connection', async (conn, info) => {
|
|
315
|
+
console.log('TT Peer2 RECON connection details:')
|
|
316
|
+
// console.log(peer2.swarm.status(topicReconnect))
|
|
317
|
+
connectionCount++
|
|
318
|
+
// Store connection for verification
|
|
319
|
+
const publicKeyHex = info.publicKey.toString('hex')
|
|
320
|
+
// Determine the correct client value from testConfig
|
|
321
|
+
const clientValue = testConfig.peer1to2.peer2.client
|
|
322
|
+
// check logic
|
|
323
|
+
let logicInfo = await logicPrepserverStatus(peer2, info, publicKeyHex)
|
|
324
|
+
// Verify reconnection logic
|
|
325
|
+
if (info.client === clientValue) { // peer1 is server
|
|
326
|
+
// expect(logicInfo.serverStatus).toBe(false)
|
|
327
|
+
// expect(logicInfo.topicKeylive.length).toBe(1)
|
|
328
|
+
expect(logicInfo.discoveryTopicInfo.firstTime).toBe(false)
|
|
329
|
+
} else {
|
|
330
|
+
// Either serverStatus is true or there's a topic set
|
|
331
|
+
expect(logicInfo.serverStatus || logicInfo.topicKeylive.length > 0).toBe(true)
|
|
332
|
+
}
|
|
333
|
+
// Ensure peer1 and peer2 are connected before peer3 connects
|
|
334
|
+
console.log('TT Peer1 and Peer2 Reconnt now -- code location')
|
|
335
|
+
// Wait until both peer1 and peer2 connections are established
|
|
336
|
+
// keep tabs on invites generated
|
|
337
|
+
peer1.setRole({ pubkey: peer1.swarm.keyPair.publicKey.toString('hex'), codename: '12345677654321', name: 'primepeer' })
|
|
338
|
+
// Create function to handle peer3 connection
|
|
339
|
+
const connectPeer3 = async () => {
|
|
340
|
+
console.log('TT Connecting peer3 now that peer1 and peer2 are connected')
|
|
341
|
+
peer3.peerJoinClient()
|
|
342
|
+
const mockPeer1 = {
|
|
343
|
+
publickey: peer1.swarm.keyPair.publicKey.toString('hex'),
|
|
344
|
+
live: false,
|
|
345
|
+
value: {
|
|
346
|
+
live: false,
|
|
347
|
+
key: peer1.swarm.keyPair.publicKey.toString('hex')
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
peer3.peerJoin(mockPeer1)
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Call connectPeer3 when connectionCount reaches 2
|
|
354
|
+
if (connectionCount === 2) {
|
|
355
|
+
console.log('TT wait 1111')
|
|
356
|
+
await connectPeer3()
|
|
357
|
+
} else {
|
|
358
|
+
// Set up a listener for when connectionCount reaches 2
|
|
359
|
+
const checkConnectionCount = setInterval(async () => {
|
|
360
|
+
console.log('TT wait 2222')
|
|
361
|
+
// put a time delay in here too
|
|
362
|
+
if (connectionCount === 2) {
|
|
363
|
+
clearInterval(checkConnectionCount)
|
|
364
|
+
console.log('TT Waiting 3 seconds before connecting peer3...')
|
|
365
|
+
await new Promise(resolve => setTimeout(resolve, 10000))
|
|
366
|
+
connectPeer3()
|
|
367
|
+
}
|
|
368
|
+
}, 100)
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// process network message
|
|
372
|
+
conn.on('data', data =>
|
|
373
|
+
// assess data
|
|
374
|
+
peer2.assessData(publicKeyHex, data)
|
|
375
|
+
)
|
|
376
|
+
if (connectionCount === 4) {
|
|
377
|
+
console.log('resolve peer two')
|
|
378
|
+
resolve()
|
|
379
|
+
}
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
peer3.swarm.on('connection', async (conn, info) => {
|
|
383
|
+
console.log('TT Peer3 FIRST connection details:')
|
|
384
|
+
connectionCount++
|
|
385
|
+
// Verify server reconnection details
|
|
386
|
+
// expect(info.publicKey).toBeDefined()
|
|
387
|
+
// expect(info.publicKey.toString('hex')).toBeDefined()
|
|
388
|
+
// expect(info.topics.length).toBe(0)
|
|
389
|
+
// expect(peer3.topicHolder['']).toBeUndefined()
|
|
390
|
+
// Store connection for verification
|
|
391
|
+
const publicKeyHex = info.publicKey.toString('hex')
|
|
392
|
+
// expect(serverPeer.peerConnect[publicKeyHex]).toBeDefined()
|
|
393
|
+
// check logic
|
|
394
|
+
if (info.publicKey === testConfig.peer1to3.peer1.publicKey) {
|
|
395
|
+
expect(info.client).toBe(testConfig.peer1to3.peer3.client) // Peer3 is client to Peer1
|
|
396
|
+
} else if (info.publicKey === testConfig.peer2to3.peer2.publicKey) {
|
|
397
|
+
expect(info.client).toBe(testConfig.peer2to3.peer3.client) // Peer3 is client to Peer2
|
|
398
|
+
}
|
|
399
|
+
// check logic
|
|
400
|
+
let logicInfo = await logicPrepserverStatus(peer3, info, publicKeyHex)
|
|
401
|
+
if (info.client === testConfig.peer2to3.peer3.client) { // peer1 is server
|
|
402
|
+
// expect(logicInfo.serverStatus).toBe(false)
|
|
403
|
+
// expect(logicInfo.topicKeylive.length).toBe(0)
|
|
404
|
+
expect(logicInfo.discoveryTopicInfo.firstTime).toBe(true)
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
// Either serverStatus is true or there's a topic set
|
|
408
|
+
expect(logicInfo.serverStatus || logicInfo.topicKeylive.length > 0).toBe(true)
|
|
409
|
+
}
|
|
410
|
+
// process network message
|
|
411
|
+
conn.on('data', data =>
|
|
412
|
+
// assess data
|
|
413
|
+
peer3.assessData(publicKeyHex, data)
|
|
414
|
+
)
|
|
415
|
+
if (connectionCount === 4) {
|
|
416
|
+
console.log('resolve peer three')
|
|
417
|
+
resolve()
|
|
418
|
+
}
|
|
419
|
+
})
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
// Wait for connection to be established
|
|
423
|
+
await reconnectionPromise
|
|
424
|
+
|
|
425
|
+
// Add timeout to prevent hanging
|
|
426
|
+
const timeout = setTimeout(() => {
|
|
427
|
+
throw new Error('Connection did not establish within timeout period')
|
|
428
|
+
}, 30000)
|
|
429
|
+
|
|
430
|
+
// Clear timeout if connection was successful
|
|
431
|
+
clearTimeout(timeout)
|
|
432
|
+
}, 40000) // 30 second timeout
|
|
433
|
+
})
|
|
434
|
+
})
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
2
|
+
import Hyperswarm from 'hyperswarm'
|
|
3
|
+
import NetworkPeers from '../../src/network/peers.js'
|
|
4
|
+
import crypto from 'crypto'
|
|
5
|
+
|
|
6
|
+
describe('Direct Peer Connection Tests', () => {
|
|
7
|
+
let clientPeer
|
|
8
|
+
let serverPeer
|
|
9
|
+
let clientSwarm
|
|
10
|
+
let serverSwarm
|
|
11
|
+
let clientSwarm2
|
|
12
|
+
let clientPeer2
|
|
13
|
+
const mockPublicKey = crypto.randomBytes(32).toString('hex')
|
|
14
|
+
const mockPeerKey = crypto.randomBytes(32).toString('hex')
|
|
15
|
+
let testConfig
|
|
16
|
+
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
// Create real swarms
|
|
19
|
+
clientSwarm = new Hyperswarm()
|
|
20
|
+
serverSwarm = new Hyperswarm()
|
|
21
|
+
clientSwarm2 = new Hyperswarm()
|
|
22
|
+
|
|
23
|
+
// Create client and server peers
|
|
24
|
+
clientPeer = new NetworkPeers({}, clientSwarm)
|
|
25
|
+
serverPeer = new NetworkPeers({}, serverSwarm)
|
|
26
|
+
clientPeer2 = new NetworkPeers({}, clientSwarm2)
|
|
27
|
+
|
|
28
|
+
testConfig = {
|
|
29
|
+
peer1to2: {
|
|
30
|
+
peer1: {
|
|
31
|
+
publicKey: clientPeer.swarm.keyPair.publicKey.toString('hex'),
|
|
32
|
+
client: true
|
|
33
|
+
},
|
|
34
|
+
peer2: {
|
|
35
|
+
publicKey: serverPeer.swarm.keyPair.publicKey.toString('hex'),
|
|
36
|
+
client: false
|
|
37
|
+
},
|
|
38
|
+
peer3: {
|
|
39
|
+
publicKey: clientPeer2.swarm.keyPair.publicKey.toString('hex'),
|
|
40
|
+
client: true
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// make client listen
|
|
46
|
+
clientPeer.peerJoinClient()
|
|
47
|
+
serverPeer.peerJoinClient()
|
|
48
|
+
clientPeer2.peerJoinClient()
|
|
49
|
+
|
|
50
|
+
// Server listens for connections
|
|
51
|
+
// console.log(clientPeer.swarm.keyPair)
|
|
52
|
+
let mockServerPeer = {
|
|
53
|
+
publickey: serverPeer.swarm.keyPair.publicKey.toString('hex'),
|
|
54
|
+
live: false,
|
|
55
|
+
value: {
|
|
56
|
+
live: false,
|
|
57
|
+
key: serverPeer.swarm.keyPair.publicKey.toString('hex')
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
clientPeer.peerJoin(mockServerPeer)
|
|
61
|
+
console.log('after join')
|
|
62
|
+
}, 10000) // 10 second timeout for setup
|
|
63
|
+
|
|
64
|
+
afterEach(async () => {
|
|
65
|
+
console.log('Cleaning up test environment')
|
|
66
|
+
await clientSwarm.destroy()
|
|
67
|
+
await serverSwarm.destroy()
|
|
68
|
+
clientPeer = null
|
|
69
|
+
serverPeer = null
|
|
70
|
+
}, 20000) // 20 second timeout for cleanup
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
it('should establish direct peer connection and handle first connections', async () => {
|
|
75
|
+
// call decision path info
|
|
76
|
+
let logicPrepserverStatus = async function (holePunch, info, publicKey) {
|
|
77
|
+
return await holePunch.prepareConnectionInfo(info, publicKey)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Listen for connection events on both peers
|
|
81
|
+
let connectionPromise = new Promise(async (resolve) => {
|
|
82
|
+
let connectionCount = 0
|
|
83
|
+
clientPeer.swarm.on('connection', async (conn, info) => {
|
|
84
|
+
console.log('TT Client connection')
|
|
85
|
+
connectionCount++
|
|
86
|
+
const publicKeyPeer1 = info.publicKey.toString('hex')
|
|
87
|
+
// Verify info object properties
|
|
88
|
+
expect(info.publicKey).toBeDefined()
|
|
89
|
+
expect(info.publicKey.toString('hex')).toBeDefined()
|
|
90
|
+
expect(info.client).toBeDefined()
|
|
91
|
+
expect(info.topics).toBeDefined()
|
|
92
|
+
expect(info.client).toBe(true)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
let logicInfo = await logicPrepserverStatus(clientPeer, info, publicKeyPeer1)
|
|
96
|
+
console.log('TT logic info')
|
|
97
|
+
console.log(logicInfo)
|
|
98
|
+
if (info.client === testConfig.peer1to2.peer1.client) { // peer1 is server
|
|
99
|
+
console.log('TT peer1 logic assertions')
|
|
100
|
+
expect(logicInfo.discoveryTopicInfo.role).toBe('client')
|
|
101
|
+
expect(logicInfo.discoveryTopicInfo.firstTime).toBe(true)
|
|
102
|
+
} else {
|
|
103
|
+
// Either serverStatus is true or there's a topic set
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Resolve when client connection is established
|
|
107
|
+
if (connectionCount === 2) {
|
|
108
|
+
resolve()
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
serverPeer.swarm.on('connection', async (conn, info) => {
|
|
113
|
+
console.log('TT Sever connection')
|
|
114
|
+
connectionCount++
|
|
115
|
+
const publicKeyPeer2 = info.publicKey.toString('hex')
|
|
116
|
+
let logicInfo = await logicPrepserverStatus(serverPeer, info, publicKeyPeer2)
|
|
117
|
+
console.log('TT logic info')
|
|
118
|
+
console.log(logicInfo)
|
|
119
|
+
// Verify info object properties
|
|
120
|
+
expect(info.publicKey).toBeDefined()
|
|
121
|
+
expect(info.publicKey.toString('hex')).toBeDefined()
|
|
122
|
+
expect(info.client).toBeDefined()
|
|
123
|
+
expect(info.topics).toBeDefined()
|
|
124
|
+
expect(info.client).toBe(false)
|
|
125
|
+
|
|
126
|
+
if (info.client === testConfig.peer1to2.peer2.client) { // peer1 is server
|
|
127
|
+
console.log('TT peer1 logic assertions')
|
|
128
|
+
expect(logicInfo.discoveryTopicInfo.role).toBe('server')
|
|
129
|
+
expect(logicInfo.discoveryTopicInfo.firstTime).toBe(true)
|
|
130
|
+
} else {
|
|
131
|
+
// Either serverStatus is true or there's a topic set
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (connectionCount === 2) {
|
|
135
|
+
resolve()
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
// Wait for connection to be established
|
|
141
|
+
await connectionPromise
|
|
142
|
+
|
|
143
|
+
// Add timeout to prevent hanging
|
|
144
|
+
const timeout = setTimeout(() => {
|
|
145
|
+
throw new Error('Connection did not establish within timeout period')
|
|
146
|
+
}, 30000)
|
|
147
|
+
|
|
148
|
+
// Clear timeout if connection was successful
|
|
149
|
+
clearTimeout(timeout)
|
|
150
|
+
}, 20000) // 50 second timeout
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
it('mock already one existing peer and then two new peers connect first time', async () => {
|
|
155
|
+
// Listen for connection events on both peers
|
|
156
|
+
|
|
157
|
+
let logicPrepserverStatus = async function (holePunch, info, publicKey) {
|
|
158
|
+
// moock existing peer on server
|
|
159
|
+
let savedPeerNetworkClient = []
|
|
160
|
+
savedPeerNetworkClient.push({
|
|
161
|
+
key: '123456789',
|
|
162
|
+
value: {
|
|
163
|
+
name: 'peerProto',
|
|
164
|
+
publickey: '123456789',
|
|
165
|
+
roletaken: true,
|
|
166
|
+
longterm: true,
|
|
167
|
+
settopic: true,
|
|
168
|
+
topic: '1235811',
|
|
169
|
+
live: false,
|
|
170
|
+
livePeerkey: ''
|
|
171
|
+
}
|
|
172
|
+
})
|
|
173
|
+
holePunch.peerNetwork = savedPeerNetworkClient
|
|
174
|
+
return await holePunch.prepareConnectionInfo(info, publicKey)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Listen for connection events on both peers
|
|
178
|
+
let connectionPromise = new Promise(async (resolve) => {
|
|
179
|
+
let connectionCount = 0
|
|
180
|
+
clientPeer.swarm.on('connection', async (conn, info) => {
|
|
181
|
+
console.log('TT Client connection')
|
|
182
|
+
connectionCount++
|
|
183
|
+
const publicKeyPeer1 = info.publicKey.toString('hex')
|
|
184
|
+
// Verify info object properties
|
|
185
|
+
expect(info.publicKey).toBeDefined()
|
|
186
|
+
expect(info.publicKey.toString('hex')).toBeDefined()
|
|
187
|
+
expect(info.client).toBeDefined()
|
|
188
|
+
expect(info.topics).toBeDefined()
|
|
189
|
+
expect(info.client).toBe(true)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
let logicInfo = await logicPrepserverStatus(clientPeer, info, publicKeyPeer1)
|
|
193
|
+
console.log('TT logic info')
|
|
194
|
+
console.log(logicInfo)
|
|
195
|
+
if (info.client === testConfig.peer1to2.peer1.client) { // peer1 is server
|
|
196
|
+
console.log('TT peer1 logic assertions')
|
|
197
|
+
expect(logicInfo.discoveryTopicInfo.role).toBe('client')
|
|
198
|
+
expect(logicInfo.discoveryTopicInfo.firstTime).toBe(true)
|
|
199
|
+
} else {
|
|
200
|
+
// Either serverStatus is true or there's a topic set
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Resolve when client connection is established
|
|
204
|
+
if (connectionCount === 2) {
|
|
205
|
+
resolve()
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
serverPeer.swarm.on('connection', async (conn, info) => {
|
|
210
|
+
console.log('TT Sever connection')
|
|
211
|
+
connectionCount++
|
|
212
|
+
const publicKeyPeer2 = info.publicKey.toString('hex')
|
|
213
|
+
let logicInfo = await logicPrepserverStatus(serverPeer, info, publicKeyPeer2)
|
|
214
|
+
console.log('TT logic info')
|
|
215
|
+
console.log(logicInfo)
|
|
216
|
+
// Verify info object properties
|
|
217
|
+
expect(info.publicKey).toBeDefined()
|
|
218
|
+
expect(info.publicKey.toString('hex')).toBeDefined()
|
|
219
|
+
expect(info.client).toBeDefined()
|
|
220
|
+
expect(info.topics).toBeDefined()
|
|
221
|
+
expect(info.client).toBe(false)
|
|
222
|
+
console.log(info.client)
|
|
223
|
+
console.log(testConfig.peer1to2.peer2.client)
|
|
224
|
+
if (info.client === testConfig.peer1to2.peer2.client) { // peer1 is server
|
|
225
|
+
console.log('TT peer1 logic assertions')
|
|
226
|
+
expect(logicInfo.discoveryTopicInfo.role).toBe('server')
|
|
227
|
+
expect(logicInfo.discoveryTopicInfo.firstTime).toBe(true)
|
|
228
|
+
} else {
|
|
229
|
+
// Either serverStatus is true or there's a topic set
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (connectionCount === 2) {
|
|
233
|
+
resolve()
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
// Wait for connection to be established
|
|
239
|
+
await connectionPromise
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
}, 20000) // 20 second timeout */
|
|
243
|
+
})
|