@streamr/trackerless-network 100.0.0-testnet-three.0 → 100.0.0-testnet-three.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.
Files changed (58) hide show
  1. package/dist/src/logic/RandomGraphNode.d.ts +1 -1
  2. package/dist/src/logic/RandomGraphNode.js +3 -2
  3. package/dist/src/logic/RandomGraphNode.js.map +1 -1
  4. package/dist/src/logic/StreamrNode.d.ts +1 -1
  5. package/dist/src/logic/StreamrNode.js +1 -1
  6. package/dist/src/logic/StreamrNode.js.map +1 -1
  7. package/dist/src/logic/createRandomGraphNode.d.ts +1 -1
  8. package/dist/src/logic/createRandomGraphNode.js +6 -5
  9. package/dist/src/logic/createRandomGraphNode.js.map +1 -1
  10. package/dist/src/logic/inspect/Inspector.d.ts +3 -0
  11. package/dist/src/logic/inspect/Inspector.js +8 -1
  12. package/dist/src/logic/inspect/Inspector.js.map +1 -1
  13. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.d.ts +1 -0
  14. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -1
  15. package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.d.ts +3 -0
  16. package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js +30 -20
  17. package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js.map +1 -1
  18. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.d.ts +3 -1
  19. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js +5 -0
  20. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js.map +1 -1
  21. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.d.ts +1 -0
  22. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.js +11 -0
  23. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.js.map +1 -1
  24. package/dist/src/proto/google/protobuf/any.js +8 -8
  25. package/dist/src/proto/google/protobuf/any.js.map +1 -1
  26. package/dist/src/proto/google/protobuf/empty.js +2 -4
  27. package/dist/src/proto/google/protobuf/empty.js.map +1 -1
  28. package/dist/src/proto/google/protobuf/timestamp.js +10 -10
  29. package/dist/src/proto/google/protobuf/timestamp.js.map +1 -1
  30. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +4 -0
  31. package/dist/src/proto/packages/dht/protos/DhtRpc.js +2 -1
  32. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
  33. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.d.ts +9 -0
  34. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js +7 -0
  35. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js.map +1 -1
  36. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.d.ts +12 -0
  37. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js +13 -2
  38. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js.map +1 -1
  39. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.server.d.ts +5 -0
  40. package/package.json +6 -6
  41. package/protos/NetworkRpc.proto +4 -0
  42. package/src/logic/RandomGraphNode.ts +6 -3
  43. package/src/logic/StreamrNode.ts +2 -2
  44. package/src/logic/createRandomGraphNode.ts +7 -6
  45. package/src/logic/inspect/Inspector.ts +15 -1
  46. package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +1 -0
  47. package/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.ts +38 -26
  48. package/src/logic/temporary-connection/TemporaryConnectionRpcLocal.ts +12 -1
  49. package/src/logic/temporary-connection/TemporaryConnectionRpcRemote.ts +11 -0
  50. package/src/proto/google/protobuf/any.ts +4 -4
  51. package/src/proto/google/protobuf/empty.ts +2 -4
  52. package/src/proto/google/protobuf/timestamp.ts +4 -4
  53. package/src/proto/packages/dht/protos/DhtRpc.ts +6 -1
  54. package/src/proto/packages/trackerless-network/protos/NetworkRpc.client.ts +12 -0
  55. package/src/proto/packages/trackerless-network/protos/NetworkRpc.server.ts +5 -0
  56. package/src/proto/packages/trackerless-network/protos/NetworkRpc.ts +17 -1
  57. package/test/unit/NeighborUpdateRpcLocal.test.ts +125 -0
  58. package/test/unit/TemporaryConnectionRpcLocal.test.ts +32 -0
@@ -13,6 +13,7 @@ interface InspectorConfig {
13
13
  connectionLocker: ConnectionLocker
14
14
  inspectionTimeout?: number
15
15
  openInspectConnection?: (peerDescriptor: PeerDescriptor, lockId: LockID) => Promise<void>
16
+ closeInspectConnection?: (peerDescriptor: PeerDescriptor, lockId: LockID) => Promise<void>
16
17
  }
17
18
 
18
19
  const logger = new Logger(module)
@@ -27,6 +28,7 @@ export class Inspector {
27
28
  private readonly connectionLocker: ConnectionLocker
28
29
  private readonly inspectionTimeout: number
29
30
  private readonly openInspectConnection: (peerDescriptor: PeerDescriptor, lockId: LockID) => Promise<void>
31
+ private readonly closeInspectConnection: (peerDescriptor: PeerDescriptor, lockId: LockID) => Promise<void>
30
32
 
31
33
  constructor(config: InspectorConfig) {
32
34
  this.streamPartId = config.streamPartId
@@ -35,6 +37,7 @@ export class Inspector {
35
37
  this.connectionLocker = config.connectionLocker
36
38
  this.inspectionTimeout = config.inspectionTimeout ?? DEFAULT_TIMEOUT
37
39
  this.openInspectConnection = config.openInspectConnection ?? this.defaultOpenInspectConnection
40
+ this.closeInspectConnection = config.closeInspectConnection ?? this.defaultCloseInspectConnection
38
41
  }
39
42
 
40
43
  async defaultOpenInspectConnection(peerDescriptor: PeerDescriptor, lockId: LockID): Promise<void> {
@@ -48,6 +51,17 @@ export class Inspector {
48
51
  this.connectionLocker.lockConnection(peerDescriptor, lockId)
49
52
  }
50
53
 
54
+ async defaultCloseInspectConnection(peerDescriptor: PeerDescriptor, lockId: LockID): Promise<void> {
55
+ const rpcRemote = new TemporaryConnectionRpcRemote(
56
+ this.localPeerDescriptor,
57
+ peerDescriptor,
58
+ this.rpcCommunicator,
59
+ TemporaryConnectionRpcClient
60
+ )
61
+ await rpcRemote.closeConnection()
62
+ this.connectionLocker.unlockConnection(peerDescriptor, lockId)
63
+ }
64
+
51
65
  async inspect(peerDescriptor: PeerDescriptor): Promise<boolean> {
52
66
  const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
53
67
  const session = new InspectSession({
@@ -63,8 +77,8 @@ export class Inspector {
63
77
  } catch (err) {
64
78
  logger.trace('Inspect session timed out, removing')
65
79
  } finally {
80
+ await this.closeInspectConnection(peerDescriptor, lockId)
66
81
  this.sessions.delete(nodeId)
67
- this.connectionLocker.unlockConnection(peerDescriptor, lockId)
68
82
  }
69
83
  return success || session.getInspectedMessageCount() < 1
70
84
  }
@@ -16,6 +16,7 @@ interface NeighborUpdateManagerConfig {
16
16
  streamPartId: StreamPartID
17
17
  rpcCommunicator: ListeningRpcCommunicator
18
18
  neighborUpdateInterval: number
19
+ neighborTargetCount: number
19
20
  }
20
21
 
21
22
  const logger = new Logger(module)
@@ -15,6 +15,7 @@ interface NeighborUpdateRpcLocalConfig {
15
15
  nearbyNodeView: NodeList
16
16
  neighborFinder: NeighborFinder
17
17
  rpcCommunicator: ListeningRpcCommunicator
18
+ neighborTargetCount: number
18
19
  }
19
20
 
20
21
  export class NeighborUpdateRpcLocal implements INeighborUpdateRpc {
@@ -25,38 +26,49 @@ export class NeighborUpdateRpcLocal implements INeighborUpdateRpc {
25
26
  this.config = config
26
27
  }
27
28
 
29
+ private updateContacts(neighborDescriptors: PeerDescriptor[]): void {
30
+ const ownNodeId = getNodeIdFromPeerDescriptor(this.config.localPeerDescriptor)
31
+ const newPeerDescriptors = neighborDescriptors.filter((peerDescriptor) => {
32
+ const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
33
+ return nodeId !== ownNodeId && !this.config.neighbors.getIds().includes(nodeId)
34
+ })
35
+ newPeerDescriptors.forEach((peerDescriptor) => this.config.nearbyNodeView.add(
36
+ new DeliveryRpcRemote(
37
+ this.config.localPeerDescriptor,
38
+ peerDescriptor,
39
+ this.config.rpcCommunicator,
40
+ DeliveryRpcClient
41
+ ))
42
+ )
43
+ }
44
+
45
+ private createResponse(removeMe: boolean): NeighborUpdate {
46
+ return {
47
+ streamPartId: this.config.streamPartId,
48
+ neighborDescriptors: this.config.neighbors.getAll().map((neighbor) => neighbor.getPeerDescriptor()),
49
+ removeMe
50
+ }
51
+ }
52
+
28
53
  // INeighborUpdateRpc server method
29
54
  async neighborUpdate(message: NeighborUpdate, context: ServerCallContext): Promise<NeighborUpdate> {
30
55
  const senderPeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
31
56
  const senderId = getNodeIdFromPeerDescriptor(senderPeerDescriptor)
32
- if (this.config.neighbors.has(senderId)) {
33
- const ownNodeId = getNodeIdFromPeerDescriptor(this.config.localPeerDescriptor)
34
- const newPeerDescriptors = message.neighborDescriptors.filter((peerDescriptor) => {
35
- const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
36
- return nodeId !== ownNodeId && !this.config.neighbors.getIds().includes(nodeId)
37
- })
38
- newPeerDescriptors.forEach((peerDescriptor) => this.config.nearbyNodeView.add(
39
- new DeliveryRpcRemote(
40
- this.config.localPeerDescriptor,
41
- peerDescriptor,
42
- this.config.rpcCommunicator,
43
- DeliveryRpcClient
44
- ))
45
- )
46
- this.config.neighborFinder.start()
47
- const response: NeighborUpdate = {
48
- streamPartId: this.config.streamPartId,
49
- neighborDescriptors: this.config.neighbors.getAll().map((neighbor) => neighbor.getPeerDescriptor()),
50
- removeMe: false
51
- }
52
- return response
57
+ this.updateContacts(message.neighborDescriptors)
58
+ if (!this.config.neighbors.has(senderId)) {
59
+ return this.createResponse(true)
53
60
  } else {
54
- const response: NeighborUpdate = {
55
- streamPartId: this.config.streamPartId,
56
- neighborDescriptors: this.config.neighbors.getAll().map((neighbor) => neighbor.getPeerDescriptor()),
57
- removeMe: true
61
+ const isOverNeighborCount = this.config.neighbors.size() > this.config.neighborTargetCount
62
+ // Motivation: We don't know the remote's neighborTargetCount setting here. We only ask to cut connections
63
+ // if the remote has a "sufficient" number of neighbors, where "sufficient" means our neighborTargetCount
64
+ // setting.
65
+ && message.neighborDescriptors.length > this.config.neighborTargetCount
66
+ if (!isOverNeighborCount) {
67
+ this.config.neighborFinder.start()
68
+ } else {
69
+ this.config.neighbors.remove(senderId)
58
70
  }
59
- return response
71
+ return this.createResponse(isOverNeighborCount)
60
72
  }
61
73
  }
62
74
  }
@@ -1,11 +1,16 @@
1
1
  import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
2
- import { TemporaryConnectionRequest, TemporaryConnectionResponse } from '../../proto/packages/trackerless-network/protos/NetworkRpc'
2
+ import {
3
+ CloseTemporaryConnection,
4
+ TemporaryConnectionRequest,
5
+ TemporaryConnectionResponse
6
+ } from '../../proto/packages/trackerless-network/protos/NetworkRpc'
3
7
  import { ITemporaryConnectionRpc } from '../../proto/packages/trackerless-network/protos/NetworkRpc.server'
4
8
  import { DhtAddress, DhtCallContext, ListeningRpcCommunicator, getNodeIdFromPeerDescriptor } from '@streamr/dht'
5
9
  import { DeliveryRpcClient } from '../../proto/packages/trackerless-network/protos/NetworkRpc.client'
6
10
  import { NodeList } from '../NodeList'
7
11
  import { DeliveryRpcRemote } from '../DeliveryRpcRemote'
8
12
  import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
13
+ import { Empty } from '../../proto/google/protobuf/empty'
9
14
 
10
15
  interface TemporaryConnectionRpcLocalConfig {
11
16
  rpcCommunicator: ListeningRpcCommunicator
@@ -47,4 +52,10 @@ export class TemporaryConnectionRpcLocal implements ITemporaryConnectionRpc {
47
52
  accepted: true
48
53
  }
49
54
  }
55
+
56
+ async closeConnection(_request: CloseTemporaryConnection, context: ServerCallContext): Promise<Empty> {
57
+ const senderId = getNodeIdFromPeerDescriptor((context as DhtCallContext).incomingSourceDescriptor!)
58
+ this.removeNode(senderId)
59
+ return {}
60
+ }
50
61
  }
@@ -15,4 +15,15 @@ export class TemporaryConnectionRpcRemote extends RpcRemote<TemporaryConnectionR
15
15
  return false
16
16
  }
17
17
  }
18
+
19
+ async closeConnection(): Promise<void> {
20
+ try {
21
+ await this.getClient().closeConnection({}, this.formDhtRpcOptions({
22
+ connect: false,
23
+ notification: true
24
+ }))
25
+ } catch (err) {
26
+ logger.trace(`closeConnection to ${getNodeIdFromPeerDescriptor(this.getPeerDescriptor())} failed: ${err}`)
27
+ }
28
+ }
18
29
  }
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.3 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "google/protobuf/any.proto" (package "google.protobuf", syntax proto3)
3
3
  // tslint:disable
4
4
  //
@@ -39,7 +39,6 @@ import type { IBinaryReader } from "@protobuf-ts/runtime";
39
39
  import { UnknownFieldHandler } from "@protobuf-ts/runtime";
40
40
  import type { PartialMessage } from "@protobuf-ts/runtime";
41
41
  import { reflectionMergePartial } from "@protobuf-ts/runtime";
42
- import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
43
42
  import { isJsonObject } from "@protobuf-ts/runtime";
44
43
  import { typeofJsonValue } from "@protobuf-ts/runtime";
45
44
  import type { JsonValue } from "@protobuf-ts/runtime";
@@ -272,8 +271,9 @@ class Any$Type extends MessageType<Any> {
272
271
  return name;
273
272
  }
274
273
  create(value?: PartialMessage<Any>): Any {
275
- const message = { typeUrl: "", value: new Uint8Array(0) };
276
- globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
274
+ const message = globalThis.Object.create((this.messagePrototype!));
275
+ message.typeUrl = "";
276
+ message.value = new Uint8Array(0);
277
277
  if (value !== undefined)
278
278
  reflectionMergePartial<Any>(this, message, value);
279
279
  return message;
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.3 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "google/protobuf/empty.proto" (package "google.protobuf", syntax proto3)
3
3
  // tslint:disable
4
4
  //
@@ -39,7 +39,6 @@ import type { BinaryReadOptions } from "@protobuf-ts/runtime";
39
39
  import type { IBinaryReader } from "@protobuf-ts/runtime";
40
40
  import type { PartialMessage } from "@protobuf-ts/runtime";
41
41
  import { reflectionMergePartial } from "@protobuf-ts/runtime";
42
- import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
43
42
  import { MessageType } from "@protobuf-ts/runtime";
44
43
  /**
45
44
  * A generic empty message that you can re-use to avoid defining duplicated
@@ -62,8 +61,7 @@ class Empty$Type extends MessageType<Empty> {
62
61
  super("google.protobuf.Empty", []);
63
62
  }
64
63
  create(value?: PartialMessage<Empty>): Empty {
65
- const message = {};
66
- globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
64
+ const message = globalThis.Object.create((this.messagePrototype!));
67
65
  if (value !== undefined)
68
66
  reflectionMergePartial<Empty>(this, message, value);
69
67
  return message;
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.3 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "google/protobuf/timestamp.proto" (package "google.protobuf", syntax proto3)
3
3
  // tslint:disable
4
4
  //
@@ -40,7 +40,6 @@ import type { IBinaryReader } from "@protobuf-ts/runtime";
40
40
  import { UnknownFieldHandler } from "@protobuf-ts/runtime";
41
41
  import type { PartialMessage } from "@protobuf-ts/runtime";
42
42
  import { reflectionMergePartial } from "@protobuf-ts/runtime";
43
- import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
44
43
  import { typeofJsonValue } from "@protobuf-ts/runtime";
45
44
  import type { JsonValue } from "@protobuf-ts/runtime";
46
45
  import type { JsonReadOptions } from "@protobuf-ts/runtime";
@@ -234,8 +233,9 @@ class Timestamp$Type extends MessageType<Timestamp> {
234
233
  return target;
235
234
  }
236
235
  create(value?: PartialMessage<Timestamp>): Timestamp {
237
- const message = { seconds: 0, nanos: 0 };
238
- globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
236
+ const message = globalThis.Object.create((this.messagePrototype!));
237
+ message.seconds = 0;
238
+ message.nanos = 0;
239
239
  if (value !== undefined)
240
240
  reflectionMergePartial<Timestamp>(this, message, value);
241
241
  return message;
@@ -339,6 +339,10 @@ export interface ConnectivityResponse {
339
339
  * @generated from protobuf field: uint32 ipAddress = 4;
340
340
  */
341
341
  ipAddress: number;
342
+ /**
343
+ * @generated from protobuf field: string version = 5;
344
+ */
345
+ version: string;
342
346
  }
343
347
  /**
344
348
  * @generated from protobuf message dht.HandshakeRequest
@@ -943,7 +947,8 @@ class ConnectivityResponse$Type extends MessageType$<ConnectivityResponse> {
943
947
  { no: 1, name: "host", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
944
948
  { no: 2, name: "natType", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
945
949
  { no: 3, name: "websocket", kind: "message", T: () => ConnectivityMethod },
946
- { no: 4, name: "ipAddress", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }
950
+ { no: 4, name: "ipAddress", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
951
+ { no: 5, name: "version", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
947
952
  ]);
948
953
  }
949
954
  }
@@ -5,6 +5,7 @@ import { NodeInfoRpc } from "./NetworkRpc";
5
5
  import type { NodeInfoResponse } from "./NetworkRpc";
6
6
  import type { NodeInfoRequest } from "./NetworkRpc";
7
7
  import { TemporaryConnectionRpc } from "./NetworkRpc";
8
+ import type { CloseTemporaryConnection } from "./NetworkRpc";
8
9
  import type { TemporaryConnectionResponse } from "./NetworkRpc";
9
10
  import type { TemporaryConnectionRequest } from "./NetworkRpc";
10
11
  import { NeighborUpdateRpc } from "./NetworkRpc";
@@ -160,6 +161,10 @@ export interface ITemporaryConnectionRpcClient {
160
161
  * @generated from protobuf rpc: openConnection(TemporaryConnectionRequest) returns (TemporaryConnectionResponse);
161
162
  */
162
163
  openConnection(input: TemporaryConnectionRequest, options?: RpcOptions): UnaryCall<TemporaryConnectionRequest, TemporaryConnectionResponse>;
164
+ /**
165
+ * @generated from protobuf rpc: closeConnection(CloseTemporaryConnection) returns (google.protobuf.Empty);
166
+ */
167
+ closeConnection(input: CloseTemporaryConnection, options?: RpcOptions): UnaryCall<CloseTemporaryConnection, Empty>;
163
168
  }
164
169
  /**
165
170
  * @generated from protobuf service TemporaryConnectionRpc
@@ -177,6 +182,13 @@ export class TemporaryConnectionRpcClient implements ITemporaryConnectionRpcClie
177
182
  const method = this.methods[0], opt = this._transport.mergeOptions(options);
178
183
  return stackIntercept<TemporaryConnectionRequest, TemporaryConnectionResponse>("unary", this._transport, method, opt, input);
179
184
  }
185
+ /**
186
+ * @generated from protobuf rpc: closeConnection(CloseTemporaryConnection) returns (google.protobuf.Empty);
187
+ */
188
+ closeConnection(input: CloseTemporaryConnection, options?: RpcOptions): UnaryCall<CloseTemporaryConnection, Empty> {
189
+ const method = this.methods[1], opt = this._transport.mergeOptions(options);
190
+ return stackIntercept<CloseTemporaryConnection, Empty>("unary", this._transport, method, opt, input);
191
+ }
180
192
  }
181
193
  /**
182
194
  * @generated from protobuf service NodeInfoRpc
@@ -3,6 +3,7 @@
3
3
  // tslint:disable
4
4
  import { NodeInfoResponse } from "./NetworkRpc";
5
5
  import { NodeInfoRequest } from "./NetworkRpc";
6
+ import { CloseTemporaryConnection } from "./NetworkRpc";
6
7
  import { TemporaryConnectionResponse } from "./NetworkRpc";
7
8
  import { TemporaryConnectionRequest } from "./NetworkRpc";
8
9
  import { NeighborUpdate } from "./NetworkRpc";
@@ -68,6 +69,10 @@ export interface ITemporaryConnectionRpc<T = ServerCallContext> {
68
69
  * @generated from protobuf rpc: openConnection(TemporaryConnectionRequest) returns (TemporaryConnectionResponse);
69
70
  */
70
71
  openConnection(request: TemporaryConnectionRequest, context: T): Promise<TemporaryConnectionResponse>;
72
+ /**
73
+ * @generated from protobuf rpc: closeConnection(CloseTemporaryConnection) returns (google.protobuf.Empty);
74
+ */
75
+ closeConnection(request: CloseTemporaryConnection, context: T): Promise<Empty>;
71
76
  }
72
77
  /**
73
78
  * @generated from protobuf service NodeInfoRpc
@@ -273,6 +273,11 @@ export interface TemporaryConnectionResponse {
273
273
  */
274
274
  accepted: boolean;
275
275
  }
276
+ /**
277
+ * @generated from protobuf message CloseTemporaryConnection
278
+ */
279
+ export interface CloseTemporaryConnection {
280
+ }
276
281
  /**
277
282
  * @generated from protobuf message StreamPartitionInfo
278
283
  */
@@ -616,6 +621,16 @@ class TemporaryConnectionResponse$Type extends MessageType<TemporaryConnectionRe
616
621
  */
617
622
  export const TemporaryConnectionResponse = new TemporaryConnectionResponse$Type();
618
623
  // @generated message type with reflection information, may provide speed optimized methods
624
+ class CloseTemporaryConnection$Type extends MessageType<CloseTemporaryConnection> {
625
+ constructor() {
626
+ super("CloseTemporaryConnection", []);
627
+ }
628
+ }
629
+ /**
630
+ * @generated MessageType for protobuf message CloseTemporaryConnection
631
+ */
632
+ export const CloseTemporaryConnection = new CloseTemporaryConnection$Type();
633
+ // @generated message type with reflection information, may provide speed optimized methods
619
634
  class StreamPartitionInfo$Type extends MessageType<StreamPartitionInfo> {
620
635
  constructor() {
621
636
  super("StreamPartitionInfo", [
@@ -696,7 +711,8 @@ export const NeighborUpdateRpc = new ServiceType("NeighborUpdateRpc", [
696
711
  * @generated ServiceType for protobuf service TemporaryConnectionRpc
697
712
  */
698
713
  export const TemporaryConnectionRpc = new ServiceType("TemporaryConnectionRpc", [
699
- { name: "openConnection", options: {}, I: TemporaryConnectionRequest, O: TemporaryConnectionResponse }
714
+ { name: "openConnection", options: {}, I: TemporaryConnectionRequest, O: TemporaryConnectionResponse },
715
+ { name: "closeConnection", options: {}, I: CloseTemporaryConnection, O: Empty }
700
716
  ]);
701
717
  /**
702
718
  * @generated ServiceType for protobuf service NodeInfoRpc
@@ -0,0 +1,125 @@
1
+ import { ListeningRpcCommunicator, getNodeIdFromPeerDescriptor } from '@streamr/dht'
2
+ import { NeighborFinder } from '../../src/logic/neighbor-discovery/NeighborFinder'
3
+ import { NeighborUpdateRpcLocal } from '../../src/logic/neighbor-discovery/NeighborUpdateRpcLocal'
4
+ import { createMockPeerDescriptor } from '../utils/utils'
5
+ import { NodeList } from '../../src/logic/NodeList'
6
+ import { StreamPartIDUtils } from '@streamr/protocol'
7
+ import { MockTransport } from '../utils/mock/Transport'
8
+ import { DeliveryRpcClient } from '../../src/proto/packages/trackerless-network/protos/NetworkRpc.client'
9
+ import { DeliveryRpcRemote } from '../../src/logic/DeliveryRpcRemote'
10
+ import { range } from 'lodash'
11
+
12
+ describe('NeighborUpdateRpcLocal', () => {
13
+
14
+ const streamPartId = StreamPartIDUtils.parse('stream#0')
15
+ const localPeerDescriptor = createMockPeerDescriptor()
16
+ const neighborTargetCount = 4
17
+
18
+ let rpcLocal: NeighborUpdateRpcLocal
19
+ let neighbors: NodeList
20
+ let nearbyNodeView: NodeList
21
+ let neighborFinder: NeighborFinder
22
+ let rpcCommunicator: ListeningRpcCommunicator
23
+
24
+ const addNeighbors = (count: number) => {
25
+ for (let i = 0; i < count; i++) {
26
+ neighbors.add(new DeliveryRpcRemote(
27
+ localPeerDescriptor,
28
+ createMockPeerDescriptor(),
29
+ rpcCommunicator,
30
+ DeliveryRpcClient
31
+ ))
32
+ }
33
+ }
34
+
35
+ beforeEach(() => {
36
+ rpcCommunicator = new ListeningRpcCommunicator('mock', new MockTransport())
37
+ neighbors = new NodeList(getNodeIdFromPeerDescriptor(localPeerDescriptor), neighborTargetCount + 1)
38
+ nearbyNodeView = new NodeList(getNodeIdFromPeerDescriptor(localPeerDescriptor), neighborTargetCount)
39
+ neighborFinder = {
40
+ start: jest.fn()
41
+ } as any
42
+
43
+ rpcLocal = new NeighborUpdateRpcLocal({
44
+ localPeerDescriptor,
45
+ neighbors,
46
+ nearbyNodeView,
47
+ neighborFinder,
48
+ streamPartId,
49
+ rpcCommunicator,
50
+ neighborTargetCount
51
+ })
52
+ })
53
+
54
+ afterEach(() => {
55
+ rpcCommunicator.destroy()
56
+ })
57
+
58
+ it('response contains neighbor list of expected size', async () => {
59
+ addNeighbors(neighborTargetCount)
60
+ const res = await rpcLocal.neighborUpdate({
61
+ streamPartId,
62
+ neighborDescriptors: [localPeerDescriptor],
63
+ removeMe: false
64
+ }, { incomingSourceDescriptor: createMockPeerDescriptor() } as any)
65
+ expect(res.neighborDescriptors.length).toEqual(neighborTargetCount)
66
+ })
67
+
68
+ it('updates contacts based on callers neighbors', async () => {
69
+ addNeighbors(neighborTargetCount)
70
+ expect(nearbyNodeView.size()).toEqual(0)
71
+ await rpcLocal.neighborUpdate({
72
+ streamPartId,
73
+ neighborDescriptors: range(neighborTargetCount).map(() => createMockPeerDescriptor()),
74
+ removeMe: false
75
+ }, { incomingSourceDescriptor: createMockPeerDescriptor() } as any)
76
+ expect(nearbyNodeView.size()).toEqual(4)
77
+ })
78
+
79
+ it('does not ask to be removed if caller is a neighbor', async () => {
80
+ const caller = createMockPeerDescriptor()
81
+ const neighbor = new DeliveryRpcRemote(
82
+ localPeerDescriptor,
83
+ caller,
84
+ rpcCommunicator,
85
+ DeliveryRpcClient
86
+ )
87
+ neighbors.add(neighbor)
88
+ const res = await rpcLocal.neighborUpdate({
89
+ streamPartId,
90
+ neighborDescriptors: [localPeerDescriptor],
91
+ removeMe: false
92
+ }, { incomingSourceDescriptor: caller } as any)
93
+ expect(res.removeMe).toEqual(false)
94
+ })
95
+
96
+ it('asks to be removed if caller is not a neighbor', async () => {
97
+ const caller = createMockPeerDescriptor()
98
+ const res = await rpcLocal.neighborUpdate({
99
+ streamPartId,
100
+ neighborDescriptors: [localPeerDescriptor],
101
+ removeMe: false
102
+ }, { incomingSourceDescriptor: caller } as any)
103
+ expect(res.removeMe).toEqual(true)
104
+ })
105
+
106
+ it('asks to be removed if caller is a neighbor and both have too many neighbors', async () => {
107
+ const caller = createMockPeerDescriptor()
108
+ const neighbor = new DeliveryRpcRemote(
109
+ localPeerDescriptor,
110
+ caller,
111
+ rpcCommunicator,
112
+ DeliveryRpcClient
113
+ )
114
+ neighbors.add(neighbor)
115
+ addNeighbors(neighborTargetCount)
116
+ const res = await rpcLocal.neighborUpdate({
117
+ streamPartId,
118
+ neighborDescriptors: [localPeerDescriptor, ...range(neighborTargetCount).map(() => createMockPeerDescriptor())],
119
+ removeMe: false
120
+ }, { incomingSourceDescriptor: caller } as any)
121
+ expect(res.removeMe).toEqual(true)
122
+ expect(neighbors.has(getNodeIdFromPeerDescriptor(caller))).toEqual(false)
123
+ })
124
+
125
+ })
@@ -0,0 +1,32 @@
1
+ import { TemporaryConnectionRpcLocal } from '../../src/logic/temporary-connection/TemporaryConnectionRpcLocal'
2
+ import { MockTransport } from '../utils/mock/Transport'
3
+ import { createMockPeerDescriptor } from '../utils/utils'
4
+ import { ListeningRpcCommunicator, getDhtAddressFromRaw } from '@streamr/dht'
5
+
6
+ describe('TemporaryConnectionRpcLocal', () => {
7
+
8
+ const peerDescriptor = createMockPeerDescriptor()
9
+ let rpcCommunicator: ListeningRpcCommunicator
10
+ let rpcLocal: TemporaryConnectionRpcLocal
11
+
12
+ beforeEach(() => {
13
+ rpcCommunicator = new ListeningRpcCommunicator('mock', new MockTransport())
14
+ rpcLocal = new TemporaryConnectionRpcLocal({
15
+ localPeerDescriptor: peerDescriptor,
16
+ rpcCommunicator
17
+ })
18
+ })
19
+
20
+ afterEach(() => {
21
+ rpcCommunicator.destroy()
22
+ })
23
+
24
+ it('Open and Close Connection', async () => {
25
+ const caller = createMockPeerDescriptor()
26
+ await rpcLocal.openConnection({}, { incomingSourceDescriptor: caller } as any)
27
+ expect(rpcLocal.getNodes().get(getDhtAddressFromRaw(caller.nodeId))).toBeDefined()
28
+ await rpcLocal.closeConnection({}, { incomingSourceDescriptor: caller } as any)
29
+ expect(rpcLocal.getNodes().get(getDhtAddressFromRaw(caller.nodeId))).toBeUndefined()
30
+ })
31
+
32
+ })