helia-coord 1.8.0 → 1.9.0
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/README.md +4 -0
- package/lib/adapters/gist.js +1 -1
- package/lib/adapters/pubsub-adapter/messaging.js +1 -1
- package/lib/use-cases/relay-use-cases.js +13 -11
- package/package.json +8 -8
- package/test/unit/adapters/encryption-adapter-unit.js +11 -0
- package/test/unit/adapters/gist.unit.adapters.js +1 -0
- package/test/unit/adapters/pubsub/messaging-adapter-unit.js +46 -23
- package/test/unit/controllers/pubsub-controller.unit.js +5 -4
- package/test/unit/use-cases/relay-use-cases-unit.js +79 -0
package/README.md
CHANGED
|
@@ -3,3 +3,7 @@
|
|
|
3
3
|
This is a fork of [ipfs-coord-esm](https://github.com/Permissionless-Software-Foundation/ipfs-coord-esm), adpted for use with [Helia](https://github.com/ipfs/helia) instead of Kubo.
|
|
4
4
|
|
|
5
5
|
Read the [dev-docs](./dev-docs) for more information.
|
|
6
|
+
|
|
7
|
+
## Node Version
|
|
8
|
+
|
|
9
|
+
Use node.js v22
|
package/lib/adapters/gist.js
CHANGED
|
@@ -62,7 +62,7 @@ class Gist {
|
|
|
62
62
|
|
|
63
63
|
// Retrieve the gist from github.com.
|
|
64
64
|
const result = await this.axios.get(gistUrl)
|
|
65
|
-
console.log('result.data: ', result.data)
|
|
65
|
+
// console.log('result.data: ', result.data)
|
|
66
66
|
|
|
67
67
|
// Get the current content of the gist.
|
|
68
68
|
const content = result.data
|
|
@@ -129,7 +129,7 @@ class Messaging {
|
|
|
129
129
|
if (!decryptedPayload) {
|
|
130
130
|
return false
|
|
131
131
|
}
|
|
132
|
-
this.log.statusLog(
|
|
132
|
+
this.log.statusLog(3, 'decrypted payload:', decryptedPayload)
|
|
133
133
|
|
|
134
134
|
// Filter ACK messages from other messages
|
|
135
135
|
if (decryptedPayload.includes('"apiName":"ACK"')) {
|
|
@@ -145,7 +145,7 @@ class RelayUseCases {
|
|
|
145
145
|
// Loop through each relay.
|
|
146
146
|
for (let i = 0; i < knownRelays.length; i++) {
|
|
147
147
|
const thisRelay = knownRelays[i]
|
|
148
|
-
|
|
148
|
+
console.log('thisRelay: ', thisRelay)
|
|
149
149
|
|
|
150
150
|
// Get connected peers
|
|
151
151
|
const connectedPeers = await this.adapters.ipfs.getPeers()
|
|
@@ -153,7 +153,7 @@ class RelayUseCases {
|
|
|
153
153
|
|
|
154
154
|
// Check if target circuit-relay is currently conected to the node.
|
|
155
155
|
const connectedPeer = connectedPeers.filter(peerId => thisRelay.ipfsId.includes(peerId))
|
|
156
|
-
|
|
156
|
+
console.log('connectedPeer: ', connectedPeer)
|
|
157
157
|
|
|
158
158
|
// Get the peer data corresponding to this relay
|
|
159
159
|
// let peerData = thisNode.peerData.filter(x => x.from.includes(thisRelay.ipfsId))
|
|
@@ -192,14 +192,17 @@ class RelayUseCases {
|
|
|
192
192
|
thisNode.peerData[peerIndex].data.connectionAddr = remoteConnection[0].remoteAddr.toString()
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
|
|
195
|
+
console.log(`Multiaddr changed to ${thisRelay.multiaddr}`)
|
|
196
196
|
|
|
197
197
|
// Debugging: log situations when the relay is connected through
|
|
198
198
|
// another circuit relay.
|
|
199
199
|
if (thisRelay.multiaddr.includes('/p2p-circuit')) {
|
|
200
200
|
for (const connection of libp2p.getConnections()) {
|
|
201
|
-
console.log('DEBUG: connection.remoteAddr: ', connection.remoteAddr.toString())
|
|
202
201
|
// Logs the PeerId string and the observed remote multiaddr of each Connection
|
|
202
|
+
this.adapters.log.statusLog(
|
|
203
|
+
2,
|
|
204
|
+
`DEBUG: connection.remoteAddr: ${connection.remoteAddr.toString()}`
|
|
205
|
+
)
|
|
203
206
|
}
|
|
204
207
|
}
|
|
205
208
|
} else {
|
|
@@ -213,11 +216,12 @@ class RelayUseCases {
|
|
|
213
216
|
{ multiaddr: thisRelay.multiaddr }
|
|
214
217
|
)
|
|
215
218
|
thisRelay.connected = connStatus.success
|
|
216
|
-
|
|
219
|
+
console.log(`thisRelay.connected: ${thisRelay.connected}`)
|
|
217
220
|
|
|
218
221
|
// Debugging: Trying to figure out the best way to select the multiaddr
|
|
219
222
|
console.log('relay multiaddr: ', thisRelay.multiaddr)
|
|
220
223
|
if (thisRelay.connected && !thisRelay.multiaddr.includes('/tcp/')) {
|
|
224
|
+
// 2/25/25 CT: Have not seen this code path executed in a long time.
|
|
221
225
|
console.log('DEBUG: thisRelay.multiaddr: ', thisRelay.multiaddr)
|
|
222
226
|
|
|
223
227
|
const libp2p = this.adapters.ipfs.ipfs.libp2p
|
|
@@ -476,12 +480,8 @@ class RelayUseCases {
|
|
|
476
480
|
|
|
477
481
|
// Get the peer data.
|
|
478
482
|
let peerData = thisNode.peerData.filter(x => {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
return false
|
|
482
|
-
}
|
|
483
|
-
// console.log(`x.data.ipfsId: ${x.data.ipfsId}`)
|
|
484
|
-
// console.log(`thisRelay.ipfsId: ${thisRelay.ipfsId}`)
|
|
483
|
+
// Skip entries with null or missing data
|
|
484
|
+
if (!x.data) return false
|
|
485
485
|
return x.data.ipfsId === thisRelay.ipfsId
|
|
486
486
|
})
|
|
487
487
|
peerData = peerData[0]
|
|
@@ -524,6 +524,8 @@ class RelayUseCases {
|
|
|
524
524
|
// Save the new metric value.
|
|
525
525
|
thisRelay.metrics.aboutLatency.push(diffTime)
|
|
526
526
|
}
|
|
527
|
+
|
|
528
|
+
return true
|
|
527
529
|
} catch (err) {
|
|
528
530
|
console.error('Error in measureRelays(): ', err)
|
|
529
531
|
throw err
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helia-coord",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "A JS library for helping IPFS peers coordinate, find a common interest, and stay connected around that interest.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
"homepage": "https://github.com/Permissionless-Software-Foundation/helia-coord#readme",
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@chainsafe/libp2p-gossipsub": "14.1.0",
|
|
24
|
-
"@chainsafe/libp2p-noise": "
|
|
25
|
-
"@chainsafe/libp2p-yamux": "
|
|
24
|
+
"@chainsafe/libp2p-noise": "17.0.0",
|
|
25
|
+
"@chainsafe/libp2p-yamux": "8.0.1",
|
|
26
26
|
"@istanbuljs/esm-loader-hook": "0.2.0",
|
|
27
27
|
"@libp2p/circuit-relay-v2": "3.2.2",
|
|
28
28
|
"@libp2p/identify": "3.0.22",
|
|
29
29
|
"@libp2p/ping": "2.0.22",
|
|
30
|
-
"@libp2p/tcp": "
|
|
30
|
+
"@libp2p/tcp": "11.0.10",
|
|
31
31
|
"@libp2p/webrtc": "5.2.2",
|
|
32
|
-
"@libp2p/websockets": "
|
|
33
|
-
"@multiformats/multiaddr": "
|
|
32
|
+
"@libp2p/websockets": "10.1.3",
|
|
33
|
+
"@multiformats/multiaddr": "13.0.1",
|
|
34
34
|
"@multiformats/multiaddr-matcher": "1.6.0",
|
|
35
35
|
"blockstore-fs": "2.0.2",
|
|
36
36
|
"chai": "4.3.6",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"delay": "6.0.0",
|
|
40
40
|
"helia": "5.2.1",
|
|
41
41
|
"lodash.clonedeep": "4.5.0",
|
|
42
|
-
"minimal-slp-wallet": "
|
|
42
|
+
"minimal-slp-wallet": "7.1.4",
|
|
43
43
|
"mocha": "10.0.0",
|
|
44
44
|
"nyc": "15.1.0",
|
|
45
45
|
"public-ip": "6.0.1",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"uuid": "9.0.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"libp2p": ">=
|
|
55
|
+
"libp2p": ">=3.1.3"
|
|
56
56
|
},
|
|
57
57
|
"exports": {
|
|
58
58
|
".": {
|
|
@@ -166,6 +166,17 @@ describe('#Adapters - Encryption', () => {
|
|
|
166
166
|
}
|
|
167
167
|
})
|
|
168
168
|
|
|
169
|
+
it('should throw and error if peer public key is not available', async () => {
|
|
170
|
+
try {
|
|
171
|
+
const peer = {}
|
|
172
|
+
await uut.encryptMsg(peer, 'testMsg')
|
|
173
|
+
|
|
174
|
+
assert.fail('Unexpected code path')
|
|
175
|
+
} catch (err) {
|
|
176
|
+
assert.include(err.message, 'Peer public key is not available yet.')
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
|
|
169
180
|
it('should encrypt a string', async () => {
|
|
170
181
|
// Mock dependencies
|
|
171
182
|
sandbox
|
|
@@ -14,13 +14,14 @@ import ipfsLib from '../../../mocks/ipfs-mock.js'
|
|
|
14
14
|
import IPFSAdapter from '../../../../lib/adapters/ipfs-adapter.js'
|
|
15
15
|
import EncryptionAdapter from '../../../../lib/adapters/encryption-adapter.js'
|
|
16
16
|
import BchAdapter from '../../../../lib/adapters/bch-adapter.js'
|
|
17
|
-
import
|
|
17
|
+
import thisNodeMock from '../../../mocks/thisnode-mocks.js'
|
|
18
18
|
import ResendMsg from '../../../../lib/adapters/pubsub-adapter/resend-msg.js'
|
|
19
19
|
|
|
20
20
|
describe('#messaging-adapter', () => {
|
|
21
21
|
let sandbox
|
|
22
22
|
let uut
|
|
23
23
|
let ipfs, ipfsAdapter
|
|
24
|
+
let thisNode
|
|
24
25
|
|
|
25
26
|
const log = {
|
|
26
27
|
statusLog: () => {}
|
|
@@ -34,6 +35,8 @@ describe('#messaging-adapter', () => {
|
|
|
34
35
|
ipfs = cloneDeep(ipfsLib)
|
|
35
36
|
ipfsAdapter = new IPFSAdapter({ ipfs, log })
|
|
36
37
|
|
|
38
|
+
thisNode = cloneDeep(thisNodeMock)
|
|
39
|
+
|
|
37
40
|
// Instantiate the Encryption adapater
|
|
38
41
|
const wallet = new SlpWallet()
|
|
39
42
|
await wallet.walletInfoPromise
|
|
@@ -165,33 +168,53 @@ describe('#messaging-adapter', () => {
|
|
|
165
168
|
assert.property(result, 'receiver')
|
|
166
169
|
assert.property(result, 'payload')
|
|
167
170
|
})
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
|
|
172
|
+
it('should throws error if sender is not found', async () => {
|
|
173
|
+
try {
|
|
174
|
+
const ipfsId = 'unknowPeerId'
|
|
175
|
+
const data = {
|
|
176
|
+
sender: ipfsId,
|
|
177
|
+
uuid: 'fake-uuid'
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
await uut.generateAckMsg(data, thisNode)
|
|
181
|
+
|
|
182
|
+
assert.fail('Unexpected code path')
|
|
183
|
+
} catch (err) {
|
|
184
|
+
console.log(err)
|
|
185
|
+
assert.include(err.message, 'Required encryption information for peer is not available.')
|
|
175
186
|
}
|
|
187
|
+
})
|
|
176
188
|
|
|
177
|
-
|
|
189
|
+
it('should catch and throw errors', async () => {
|
|
190
|
+
try {
|
|
191
|
+
await uut.generateAckMsg()
|
|
178
192
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
193
|
+
assert.fail('Unexpected code path')
|
|
194
|
+
} catch (err) {
|
|
195
|
+
console.log(err)
|
|
196
|
+
assert.include(err.message, 'Cannot read')
|
|
197
|
+
}
|
|
198
|
+
})
|
|
185
199
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
200
|
+
it('should throw an error if peerData is not specified', async () => {
|
|
201
|
+
try {
|
|
202
|
+
const ipfsId = '12D3KooWHS5A6Ey4V8fLWD64jpPn2EKi4r4btGN6FfkNgMTnfqVa'
|
|
203
|
+
const data = {
|
|
204
|
+
sender: ipfsId,
|
|
205
|
+
uuid: 'fake-uuid'
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
thisNode.peerData = []
|
|
209
|
+
|
|
210
|
+
const result = await uut.generateAckMsg(data, thisNode)
|
|
211
|
+
console.log(result)
|
|
189
212
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
213
|
+
assert.fail('Unexpected code path')
|
|
214
|
+
} catch (err) {
|
|
215
|
+
assert.include(err.message, 'Required encryption information for peer is not available.')
|
|
216
|
+
}
|
|
217
|
+
})
|
|
195
218
|
})
|
|
196
219
|
|
|
197
220
|
describe('#publishToPubsubChannel', () => {
|
|
@@ -106,11 +106,12 @@ describe('#Pubsub-Controller', () => {
|
|
|
106
106
|
assert.equal(result, false)
|
|
107
107
|
})
|
|
108
108
|
})
|
|
109
|
-
describe('#coinjoinPubsubHandler (default)', () => {
|
|
110
|
-
it('should return true', async () => {
|
|
111
|
-
const result = await uut.coinjoinPubsubHandler()
|
|
112
109
|
|
|
113
|
-
|
|
110
|
+
describe('#coinjoinPubsubHandler', () => {
|
|
111
|
+
it('should always return true', () => {
|
|
112
|
+
const result = uut.coinjoinPubsubHandler()
|
|
113
|
+
|
|
114
|
+
assert.equal(result, true)
|
|
114
115
|
})
|
|
115
116
|
})
|
|
116
117
|
})
|
|
@@ -298,6 +298,85 @@ describe('#relay-Use-Cases', () => {
|
|
|
298
298
|
|
|
299
299
|
assert.equal(result, false)
|
|
300
300
|
})
|
|
301
|
+
|
|
302
|
+
it('Should log when CR is connected through another CR, and does not have a tcp transport', async () => {
|
|
303
|
+
// Force relay data to have a p2p-circuit multiaddr
|
|
304
|
+
// mockData.mockRelayData[0].multiaddr = '/ip4/116.203.193.74/tcp/4001/ipfs/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL'
|
|
305
|
+
mockData.mockRelayData[0].multiaddr = '/ip4/116.203.193.74/udp/4001/ipfs/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL/p2p-circuit/p2p/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL'
|
|
306
|
+
|
|
307
|
+
// Force circuit relay to be used.
|
|
308
|
+
thisNode.relayData = mockData.mockRelayData
|
|
309
|
+
|
|
310
|
+
// Force mock circuit relay to appear as being already connected.
|
|
311
|
+
mockData.connectedPeerList01.push(mockData.mockRelayData[0].ipfsId)
|
|
312
|
+
|
|
313
|
+
// Force entity data with implicit multiaddr, which will will overwrite
|
|
314
|
+
// the explicit multiaddr provided by the realy.
|
|
315
|
+
thisNode.peerData.push({
|
|
316
|
+
from: 'QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL',
|
|
317
|
+
data: {
|
|
318
|
+
connectionAddr: 'fake-multiaddr'
|
|
319
|
+
}
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
// Mock dependencies
|
|
323
|
+
sandbox.stub(uut, 'sortRelays').returns(thisNode.relayData)
|
|
324
|
+
sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.connectedPeerList01)
|
|
325
|
+
sandbox.stub(uut.adapters.ipfs.ipfs.libp2p, 'getConnections').returns([{
|
|
326
|
+
remoteAddr: '/ip4/116.203.193.74/udp/4001/ipfs/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL/p2p-circuit/p2p/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL'
|
|
327
|
+
}])
|
|
328
|
+
|
|
329
|
+
// uut.state.relays = crMockData.circuitRelays
|
|
330
|
+
const result = await uut.connectToCRs(thisNode)
|
|
331
|
+
|
|
332
|
+
console.log('thisNode.peerData: ', thisNode.peerData)
|
|
333
|
+
|
|
334
|
+
// Assert function executed successfully.
|
|
335
|
+
assert.equal(result, true)
|
|
336
|
+
|
|
337
|
+
// Assert that the multiaddr was overwritten
|
|
338
|
+
// assert.include(thisNode.peerData[0].data.connectionAddr, 'tcp')
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
it('Should log when CR makes a new connection through another CR, and does not have a tcp transport', async () => {
|
|
342
|
+
// Force relay data to have a p2p-circuit multiaddr
|
|
343
|
+
// mockData.mockRelayData[0].multiaddr = '/ip4/116.203.193.74/tcp/4001/ipfs/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL'
|
|
344
|
+
mockData.mockRelayData[0].multiaddr = '/ip4/116.203.193.74/udp/4001/ipfs/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL/p2p-circuit/p2p/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL'
|
|
345
|
+
|
|
346
|
+
// Force circuit relay to be used.
|
|
347
|
+
thisNode.relayData = mockData.mockRelayData
|
|
348
|
+
|
|
349
|
+
// Force mock circuit relay to appear as being already connected.
|
|
350
|
+
// mockData.connectedPeerList01.push(mockData.mockRelayData[0].ipfsId)
|
|
351
|
+
|
|
352
|
+
// Force entity data with implicit multiaddr, which will will overwrite
|
|
353
|
+
// the explicit multiaddr provided by the realy.
|
|
354
|
+
thisNode.peerData.push({
|
|
355
|
+
from: 'QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL',
|
|
356
|
+
data: {
|
|
357
|
+
connectionAddr: 'fake-multiaddr'
|
|
358
|
+
}
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
// Mock dependencies
|
|
362
|
+
sandbox.stub(uut, 'sortRelays').returns(thisNode.relayData)
|
|
363
|
+
sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.connectedPeerList01)
|
|
364
|
+
sandbox.stub(uut.adapters.ipfs.ipfs.libp2p, 'getConnections').returns([{
|
|
365
|
+
remoteAddr: '/ip4/116.203.193.74/udp/4001/ipfs/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL/p2p-circuit/p2p/QmNZktxkfScScnHCFSGKELH3YRqdxHQ3Le9rAoRLhZ6vgL'
|
|
366
|
+
}])
|
|
367
|
+
sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves({ success: true })
|
|
368
|
+
|
|
369
|
+
// uut.state.relays = crMockData.circuitRelays
|
|
370
|
+
const result = await uut.connectToCRs(thisNode)
|
|
371
|
+
|
|
372
|
+
console.log('thisNode.peerData: ', thisNode.peerData)
|
|
373
|
+
|
|
374
|
+
// Assert function executed successfully.
|
|
375
|
+
assert.equal(result, true)
|
|
376
|
+
|
|
377
|
+
// Assert that the multiaddr was overwritten
|
|
378
|
+
// assert.include(thisNode.peerData[0].data.connectionAddr, 'tcp')
|
|
379
|
+
})
|
|
301
380
|
})
|
|
302
381
|
|
|
303
382
|
describe('#addRelay', () => {
|