helia-coord 1.2.1 → 1.2.2
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/lib/controllers/timer-controller.js +3 -0
- package/lib/use-cases/relay-use-cases.js +44 -1
- package/lib/use-cases/this-node-use-cases.js +58 -25
- package/package.json +1 -1
- package/test/mocks/use-case-mocks.js +2 -1
- package/test/unit/use-cases/relay-use-cases-unit.js +32 -2
- package/test/unit/use-cases/this-node-use-cases-unit.js +30 -1
|
@@ -120,6 +120,9 @@ class TimerControllers {
|
|
|
120
120
|
// Disable the timer while processing is happening.
|
|
121
121
|
clearInterval(this.circuitRelayTimerHandle)
|
|
122
122
|
|
|
123
|
+
// Renew connections to V1 Circuit Relays
|
|
124
|
+
await useCases.relays.connectToV1Relays()
|
|
125
|
+
|
|
123
126
|
// Remove any duplicate entries
|
|
124
127
|
useCases.relays.removeDuplicates(thisNode)
|
|
125
128
|
|
|
@@ -18,6 +18,23 @@ class RelayUseCases {
|
|
|
18
18
|
'Must inject instance of adapters when instantiating Relay Use Cases library.'
|
|
19
19
|
)
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
// Initialize v1 relay list. Allows user to overwrite with local config.
|
|
23
|
+
this.v1Relays = []
|
|
24
|
+
if (localConfig.v1Relays) {
|
|
25
|
+
this.v1Relays = localConfig.v1Relays
|
|
26
|
+
// console.log('v1Relays: ', this.v1Relays)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Bind 'this' object to all subfunctions
|
|
30
|
+
this.connectToV1Relays = this.connectToV1Relays.bind(this)
|
|
31
|
+
this.initializeRelays = this.initializeRelays.bind(this)
|
|
32
|
+
this.getCRGist = this.getCRGist.bind(this)
|
|
33
|
+
this.connectToCRs = this.connectToCRs.bind(this)
|
|
34
|
+
this.sortRelays = this.sortRelays.bind(this)
|
|
35
|
+
this.addRelay = this.addRelay.bind(this)
|
|
36
|
+
this.measureRelays = this.measureRelays.bind(this)
|
|
37
|
+
this.removeDuplicates = this.removeDuplicates.bind(this)
|
|
21
38
|
}
|
|
22
39
|
|
|
23
40
|
// Connect to the pre-programmed circuit relays for the first time at startup.
|
|
@@ -183,11 +200,35 @@ class RelayUseCases {
|
|
|
183
200
|
// `status: ${now.toLocaleString()}: Renewed connections to all known Circuit Relay nodes.`
|
|
184
201
|
// )
|
|
185
202
|
} catch (err) {
|
|
186
|
-
console.
|
|
203
|
+
console.error('Error in connectToCRs()')
|
|
187
204
|
return false
|
|
188
205
|
}
|
|
189
206
|
}
|
|
190
207
|
|
|
208
|
+
// If a list of v1 Circuit Relays is provided, then renew connections to them.
|
|
209
|
+
async connectToV1Relays (relays) {
|
|
210
|
+
try {
|
|
211
|
+
for (let i = 0; i < this.v1Relays.length; i++) {
|
|
212
|
+
const thisRelay = this.v1Relays[i]
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
this.adapters.log.statusLog(2, `Connecting to v1 Relay: ${thisRelay}`)
|
|
216
|
+
|
|
217
|
+
await this.adapters.ipfs.connectToPeer(
|
|
218
|
+
{ multiaddr: thisRelay }
|
|
219
|
+
)
|
|
220
|
+
} catch (err) {
|
|
221
|
+
/* exit quietly */
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return true
|
|
226
|
+
} catch (err) {
|
|
227
|
+
console.error('Error in connectToV1Relays()')
|
|
228
|
+
throw err
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
191
232
|
// Sort the relay data relative to the measured latency metrics.
|
|
192
233
|
sortRelays (relayData) {
|
|
193
234
|
try {
|
|
@@ -299,6 +340,8 @@ class RelayUseCases {
|
|
|
299
340
|
if (x.includes('udp')) return false
|
|
300
341
|
if (x.includes('quic')) return false
|
|
301
342
|
if (x.includes('p2p-circuit')) return false
|
|
343
|
+
if (x.includes('192.168.')) return false
|
|
344
|
+
if (x.includes('172.16.')) return false
|
|
302
345
|
return true
|
|
303
346
|
})
|
|
304
347
|
// console.log('filteredMultiaddrs: ', filteredMultiaddrs)
|
|
@@ -2,13 +2,10 @@
|
|
|
2
2
|
Use Cases library for the thisNode entity.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
// Local libraries
|
|
5
6
|
import ThisNodeEntity from '../entities/this-node-entity.js'
|
|
6
7
|
import Schema from './schema.js'
|
|
7
8
|
|
|
8
|
-
// A global variable that maintains scope to the instance of this class, when
|
|
9
|
-
// the context of 'this' is lost.
|
|
10
|
-
let _this
|
|
11
|
-
|
|
12
9
|
class ThisNodeUseCases {
|
|
13
10
|
constructor (localConfig = {}) {
|
|
14
11
|
// Dependency Injection.
|
|
@@ -31,7 +28,22 @@ class ThisNodeUseCases {
|
|
|
31
28
|
// Additional information for connecting to the circuit relay.
|
|
32
29
|
this.circuitRelayInfo = localConfig.circuitRelayInfo
|
|
33
30
|
|
|
34
|
-
|
|
31
|
+
// Initialize v1 relay list. Allows user to overwrite with local config.
|
|
32
|
+
this.v1Relays = []
|
|
33
|
+
if (localConfig.v1Relays) {
|
|
34
|
+
this.v1Relays = localConfig.v1Relays
|
|
35
|
+
// console.log('v1Relays: ', this.v1Relays)
|
|
36
|
+
}
|
|
37
|
+
console.log('this-node-use-cases.js v1Relays: ', this.v1Relays)
|
|
38
|
+
|
|
39
|
+
// Bind 'this' object to all subfunctions
|
|
40
|
+
this.updateUseCases = this.updateUseCases.bind(this)
|
|
41
|
+
this.createSelf = this.createSelf.bind(this)
|
|
42
|
+
this.addSubnetPeer = this.addSubnetPeer.bind(this)
|
|
43
|
+
this.isFreshPeer = this.isFreshPeer.bind(this)
|
|
44
|
+
this.refreshPeerConnections = this.refreshPeerConnections.bind(this)
|
|
45
|
+
this.enforceBlacklist = this.enforceBlacklist.bind(this)
|
|
46
|
+
this.enforceWhitelist = this.enforceWhitelist.bind(this)
|
|
35
47
|
}
|
|
36
48
|
|
|
37
49
|
// Update this instance with copies of the other Use Case libraries.
|
|
@@ -107,60 +119,60 @@ class ThisNodeUseCases {
|
|
|
107
119
|
// console.log('announceObj: ', announceObj)
|
|
108
120
|
|
|
109
121
|
// Exit if the announcement object is stale.
|
|
110
|
-
if (!
|
|
122
|
+
if (!this.isFreshPeer(announceObj)) return
|
|
111
123
|
|
|
112
124
|
const thisPeerId = announceObj.from.toString()
|
|
113
|
-
|
|
125
|
+
this.adapters.log.statusLog(
|
|
114
126
|
2,
|
|
115
127
|
`announcement recieved from ${thisPeerId}`
|
|
116
128
|
)
|
|
117
129
|
|
|
118
|
-
|
|
130
|
+
this.adapters.log.statusLog(
|
|
119
131
|
3,
|
|
120
132
|
`announcement recieved from ${thisPeerId}: `,
|
|
121
133
|
announceObj
|
|
122
134
|
)
|
|
123
135
|
|
|
124
|
-
// console.log('
|
|
136
|
+
// console.log('this.thisNode.peerList: ', this.thisNode.peerList)
|
|
125
137
|
|
|
126
138
|
// Add a timestamp.
|
|
127
139
|
const now = new Date()
|
|
128
140
|
announceObj.data.updatedAt = now.toISOString()
|
|
129
141
|
|
|
130
142
|
// If the peer is not already in the list of known peers, then add it.
|
|
131
|
-
if (!
|
|
132
|
-
|
|
143
|
+
if (!this.thisNode.peerList.includes(thisPeerId)) {
|
|
144
|
+
this.adapters.log.statusLog(1, `New peer found: ${thisPeerId}`)
|
|
133
145
|
|
|
134
146
|
// Add this peer to the list of subnet peers tracked by this node.
|
|
135
|
-
|
|
147
|
+
this.thisNode.peerList.push(thisPeerId)
|
|
136
148
|
|
|
137
149
|
// Add the announcement data object to the peerData array tracked by This Node.
|
|
138
|
-
|
|
150
|
+
this.thisNode.peerData.push(announceObj)
|
|
139
151
|
|
|
140
152
|
// Subscribe to pubsub channel for private messages to peer.
|
|
141
153
|
// Ignore any messages on this channel, since it is only used for
|
|
142
154
|
// broadcasting encrypted messages to the new peer, and they will
|
|
143
155
|
// respond on our own channel.
|
|
144
|
-
|
|
145
|
-
//
|
|
146
|
-
|
|
156
|
+
this.adapters.ipfs.ipfs.libp2p.services.pubsub.subscribe(thisPeerId)
|
|
157
|
+
// this.adapters.ipfs.ipfs.libp2p.services.pubsub.addEventListener('message', (msg) => {})
|
|
158
|
+
this.adapters.log.statusLog(2, `Subscribed to peer pubsub channel ${thisPeerId}`)
|
|
147
159
|
|
|
148
160
|
// If the new peer has the isCircuitRelay flag set, then try to add it
|
|
149
161
|
// to the list of Circuit Relays.
|
|
150
162
|
if (announceObj.data.isCircuitRelay) {
|
|
151
|
-
// console.log('
|
|
152
|
-
await
|
|
163
|
+
// console.log('this.thisNode: ', this.thisNode)
|
|
164
|
+
await this.useCases.relays.addRelay(thisPeerId, this.thisNode)
|
|
153
165
|
}
|
|
154
166
|
} else {
|
|
155
167
|
// Peer already exists in the list.
|
|
156
168
|
// console.log(`debug: Updating existing peer: ${thisPeerId}`)
|
|
157
169
|
|
|
158
170
|
// Get the data for this peer.
|
|
159
|
-
let thisPeerData =
|
|
171
|
+
let thisPeerData = this.thisNode.peerData.filter(
|
|
160
172
|
x => x.from === thisPeerId
|
|
161
173
|
)
|
|
162
174
|
thisPeerData = thisPeerData[0]
|
|
163
|
-
const dataIndex =
|
|
175
|
+
const dataIndex = this.thisNode.peerData.indexOf(thisPeerData)
|
|
164
176
|
// console.log(`dataIndex: ${dataIndex}`)
|
|
165
177
|
|
|
166
178
|
// If the new announceObj is older than the last announceObj, then
|
|
@@ -172,7 +184,7 @@ class ThisNodeUseCases {
|
|
|
172
184
|
}
|
|
173
185
|
|
|
174
186
|
// Replace the old data with the new data.
|
|
175
|
-
|
|
187
|
+
this.thisNode.peerData[dataIndex] = announceObj
|
|
176
188
|
}
|
|
177
189
|
|
|
178
190
|
// console.log(`addSubnetPeer() finished processing pubsub message from ${announceObj.from}`)
|
|
@@ -181,7 +193,7 @@ class ThisNodeUseCases {
|
|
|
181
193
|
} catch (err) {
|
|
182
194
|
console.error('Error in this-node-use-cases.js/addSubnetPeer(): ', err)
|
|
183
195
|
|
|
184
|
-
|
|
196
|
+
this.adapters.log.statusLog(
|
|
185
197
|
2,
|
|
186
198
|
'Error in this-node-use-cases.js/addSubnetPeer(): ',
|
|
187
199
|
err
|
|
@@ -274,10 +286,12 @@ class ThisNodeUseCases {
|
|
|
274
286
|
const sortedRelays = this.thisNode.useCases.relays.sortRelays(relays)
|
|
275
287
|
// console.log(`sortedRelays: ${JSON.stringify(sortedRelays, null, 2)}`)
|
|
276
288
|
|
|
289
|
+
let connected = false
|
|
290
|
+
|
|
277
291
|
// Loop through each known circuit relay and attempt to connect to the
|
|
278
292
|
// peer through a relay.
|
|
279
|
-
for (let
|
|
280
|
-
const thisRelay = sortedRelays[
|
|
293
|
+
for (let j = 0; j < sortedRelays.length; j++) {
|
|
294
|
+
const thisRelay = sortedRelays[j]
|
|
281
295
|
// console.log(`thisRelay: ${JSON.stringify(thisRelay, null, 2)}`)
|
|
282
296
|
|
|
283
297
|
// Generate a multiaddr for connecting to the peer through a circuit relay.
|
|
@@ -289,7 +303,7 @@ class ThisNodeUseCases {
|
|
|
289
303
|
this.adapters.log.statusLog(2, `refreshPeerConnections() connecting to peer with this multiaddr: ${multiaddr}`)
|
|
290
304
|
|
|
291
305
|
// Attempt to connect to the node through a circuit relay.
|
|
292
|
-
|
|
306
|
+
connected = await this.adapters.ipfs.connectToPeer({ multiaddr })
|
|
293
307
|
|
|
294
308
|
// If the connection was successful, break out of the relay loop.
|
|
295
309
|
// Otherwise try to connect through the next relay.
|
|
@@ -303,6 +317,25 @@ class ThisNodeUseCases {
|
|
|
303
317
|
}
|
|
304
318
|
}
|
|
305
319
|
}
|
|
320
|
+
|
|
321
|
+
// If we could not connect to the node through the v2 Circuit Relays,
|
|
322
|
+
// try connecting to it through the v1 Circuit Relays.
|
|
323
|
+
if (!connected) {
|
|
324
|
+
for (let j = 0; j < this.v1Relays.length; j++) {
|
|
325
|
+
const thisV1Relay = this.v1Relays[j]
|
|
326
|
+
|
|
327
|
+
// Generate a multiaddr for connecting to the peer through a circuit relay.
|
|
328
|
+
const multiaddr = `${thisV1Relay.multiaddr}/p2p-circuit/p2p/${thisPeer}`
|
|
329
|
+
|
|
330
|
+
console.log(`refreshPeerConnections() connecting to peer through V1 Circuit Relay with this multiaddr: ${multiaddr}`)
|
|
331
|
+
this.adapters.log.statusLog(2, `refreshPeerConnections() connecting to peer through V1 Circuit Relay with this multiaddr: ${multiaddr}`)
|
|
332
|
+
|
|
333
|
+
// Attempt to connect to the node through a circuit relay.
|
|
334
|
+
connected = await this.adapters.ipfs.connectToPeer({ multiaddr })
|
|
335
|
+
|
|
336
|
+
if (connected) break
|
|
337
|
+
}
|
|
338
|
+
}
|
|
306
339
|
}
|
|
307
340
|
|
|
308
341
|
const now = new Date()
|
package/package.json
CHANGED
|
@@ -34,7 +34,8 @@ describe('#relay-Use-Cases', () => {
|
|
|
34
34
|
uut = new RelayUseCases({
|
|
35
35
|
adapters,
|
|
36
36
|
statusLog: () => {
|
|
37
|
-
}
|
|
37
|
+
},
|
|
38
|
+
v1Relays: ['fake-multiaddr']
|
|
38
39
|
})
|
|
39
40
|
})
|
|
40
41
|
|
|
@@ -432,7 +433,9 @@ describe('#relay-Use-Cases', () => {
|
|
|
432
433
|
'ip4/udp/123.456.789.1/addr1',
|
|
433
434
|
'ip4/quic/123.456.789.1/addr1',
|
|
434
435
|
'ip4/tcp/123.456.789.1/p2p-circuit/p2p/addr1',
|
|
435
|
-
'/ip4/addr1'
|
|
436
|
+
'/ip4/addr1',
|
|
437
|
+
'/ip4/192.168.0.1/addr1',
|
|
438
|
+
'/ip4/172.16.0.1/addr1'
|
|
436
439
|
],
|
|
437
440
|
isCircuitRelay: true
|
|
438
441
|
}
|
|
@@ -680,4 +683,31 @@ describe('#relay-Use-Cases', () => {
|
|
|
680
683
|
}
|
|
681
684
|
})
|
|
682
685
|
})
|
|
686
|
+
|
|
687
|
+
describe('#connectToV1Relays', () => {
|
|
688
|
+
it('should connect to a list of v1 Circuit Relays', async () => {
|
|
689
|
+
// Mock dependencies
|
|
690
|
+
sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves()
|
|
691
|
+
|
|
692
|
+
uut.v1Relays = ['fake-multiaddr']
|
|
693
|
+
|
|
694
|
+
const result = await uut.connectToV1Relays()
|
|
695
|
+
|
|
696
|
+
assert.equal(result, true)
|
|
697
|
+
})
|
|
698
|
+
|
|
699
|
+
it('should catch, report, and throw errors', async () => {
|
|
700
|
+
try {
|
|
701
|
+
// Force and error
|
|
702
|
+
uut.v1Relays = null
|
|
703
|
+
|
|
704
|
+
await uut.connectToV1Relays()
|
|
705
|
+
|
|
706
|
+
assert.fail('Unexpected code path')
|
|
707
|
+
} catch (err) {
|
|
708
|
+
// console.log(err)
|
|
709
|
+
assert.include(err.message, 'Cannot read')
|
|
710
|
+
}
|
|
711
|
+
})
|
|
712
|
+
})
|
|
683
713
|
})
|
|
@@ -23,7 +23,8 @@ describe('#thisNode-Use-Cases', () => {
|
|
|
23
23
|
sandbox = sinon.createSandbox()
|
|
24
24
|
|
|
25
25
|
uut = new ThisNodeUseCases({
|
|
26
|
-
adapters
|
|
26
|
+
adapters,
|
|
27
|
+
v1Relays: ['fake-addr']
|
|
27
28
|
})
|
|
28
29
|
|
|
29
30
|
const useCases = new UseCasesMock()
|
|
@@ -235,6 +236,34 @@ describe('#thisNode-Use-Cases', () => {
|
|
|
235
236
|
assert.equal(result, true)
|
|
236
237
|
})
|
|
237
238
|
|
|
239
|
+
it('should connect over v1 Circuit Relay if v2 Circuit Relays fail', async () => {
|
|
240
|
+
await uut.createSelf({ type: 'node.js' })
|
|
241
|
+
// Add a peer that is not in the list of connected peers.
|
|
242
|
+
const ipfsId = 'QmbyYXKbnAmMbMGo8LRBZ58jYs58anqUzY1m4jxDmhDsje'
|
|
243
|
+
uut.thisNode.peerList = [ipfsId]
|
|
244
|
+
uut.thisNode.peerData = [{ from: ipfsId }]
|
|
245
|
+
|
|
246
|
+
// Add a peer
|
|
247
|
+
await uut.addSubnetPeer(mockData.announceObj)
|
|
248
|
+
|
|
249
|
+
// Force circuit relay to be used.
|
|
250
|
+
uut.thisNode.relayData = mockData.mockRelayData
|
|
251
|
+
|
|
252
|
+
// Mock dependencies
|
|
253
|
+
sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.swarmPeers)
|
|
254
|
+
sandbox.stub(uut, 'isFreshPeer').returns(true)
|
|
255
|
+
sandbox.stub(uut.adapters.ipfs, 'connectToPeer')
|
|
256
|
+
.onCall(0).resolves(false)
|
|
257
|
+
.onCall(1).resolves(true)
|
|
258
|
+
|
|
259
|
+
uut.v1Relays = ['fake-v1-relay']
|
|
260
|
+
|
|
261
|
+
// Connect to that peer.
|
|
262
|
+
const result = await uut.refreshPeerConnections()
|
|
263
|
+
|
|
264
|
+
assert.equal(result, true)
|
|
265
|
+
})
|
|
266
|
+
|
|
238
267
|
it('should skip if peer is stale', async () => {
|
|
239
268
|
await uut.createSelf({ type: 'node.js' })
|
|
240
269
|
// Add a peer that is not in the list of connected peers.
|