Skip to content

Commit 784e512

Browse files
authored
refactor(trackerless-network): unify naming and refactor selectParallelTargets (#3156)
## Summary No longer call nodes that are attempted as neighbors neighbors, instead call them targets. Added getExcludedIds helper function to remove duplicate code. Added clearer comments to explain the control flow. Fixed a bug where nodes were pushed to `excludedIds` too soon.
1 parent 41fa120 commit 784e512

File tree

1 file changed

+44
-47
lines changed
  • packages/trackerless-network/src/content-delivery-layer/neighbor-discovery

1 file changed

+44
-47
lines changed

packages/trackerless-network/src/content-delivery-layer/neighbor-discovery/Handshaker.ts

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -69,56 +69,53 @@ export class Handshaker {
6969

7070
private async selectParallelTargetsAndHandshake(excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
7171
const exclude = excludedIds.concat(this.options.neighbors.getIds())
72-
const neighbors = this.selectParallelTargets(exclude)
73-
neighbors.forEach((contact) => this.options.ongoingHandshakes.add(toNodeId(contact.getPeerDescriptor())))
74-
return this.doParallelHandshakes(neighbors, exclude)
72+
const targets = this.selectParallelTargets(exclude)
73+
targets.forEach((contact) => this.options.ongoingHandshakes.add(toNodeId(contact.getPeerDescriptor())))
74+
return this.doParallelHandshakes(targets, exclude)
7575
}
7676

7777
private selectParallelTargets(excludedIds: DhtAddress[]): HandshakeRpcRemote[] {
78-
const neighbors: Map<DhtAddress, ContentDeliveryRpcRemote> = new Map()
79-
// If the node has 0 neighbors find a node in the stream with a WS server to connect to for faster time to data.
78+
const targets = new Map<DhtAddress, ContentDeliveryRpcRemote>()
79+
const getExcludedIds = () => [...excludedIds, ...Array.from(targets.keys())]
80+
81+
// Step 1: If no neighbors, try to find a WebSocket node first
8082
if (this.options.neighbors.size() === 0) {
81-
const wsNode = this.options.nearbyNodeView.getFirst(
82-
[...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[],
83-
true
84-
)
83+
const wsNode = this.options.nearbyNodeView.getFirst(getExcludedIds(), true)
8584
if (wsNode) {
8685
const wsNodeId = toNodeId(wsNode.getPeerDescriptor())
87-
excludedIds.push(wsNodeId)
88-
neighbors.set(wsNodeId, wsNode)
89-
}
86+
targets.set(wsNodeId, wsNode)
87+
}
9088
}
91-
// Add the closest left and then right contacts from the ring if possible.
92-
const left = this.options.leftNodeView.getFirst([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
93-
const right = this.options.rightNodeView.getFirst([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
89+
90+
// Step 2: Add left and right contacts from the ring
91+
const left = this.options.leftNodeView.getFirst(getExcludedIds())
92+
const right = this.options.rightNodeView.getFirst(getExcludedIds())
9493
if (left) {
95-
neighbors.set(toNodeId(left.getPeerDescriptor()), left)
94+
targets.set(toNodeId(left.getPeerDescriptor()), left)
9695
}
9796
if (right) {
98-
neighbors.set(toNodeId(right.getPeerDescriptor()), right)
97+
targets.set(toNodeId(right.getPeerDescriptor()), right)
9998
}
100-
// If there is still room add the closest contact based on the kademlia metric
101-
if (neighbors.size < PARALLEL_HANDSHAKE_COUNT) {
102-
const first = this.options.nearbyNodeView.getFirst([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
103-
if (first) {
104-
neighbors.set(toNodeId(first.getPeerDescriptor()), first)
99+
// Step 3: Add closest contact based on Kademlia metric if needed
100+
if (targets.size < PARALLEL_HANDSHAKE_COUNT) {
101+
const closest = this.options.nearbyNodeView.getFirst(getExcludedIds())
102+
if (closest) {
103+
targets.set(toNodeId(closest.getPeerDescriptor()), closest)
105104
}
106105
}
107-
const getExcludedFromRandomView = () => [
108-
...excludedIds,
109-
...Array.from(neighbors.values()).map((neighbor) => toNodeId(neighbor.getPeerDescriptor()))
110-
]
111-
// If there is still room add a random contact until PARALLEL_HANDSHAKE_COUNT is reached
112-
while (
113-
neighbors.size < PARALLEL_HANDSHAKE_COUNT
114-
&& this.options.randomNodeView.size(getExcludedFromRandomView()) > 0
115-
) {
116-
const random = this.options.randomNodeView.getRandom([...excludedIds, ...Array.from(neighbors.keys())] as DhtAddress[])
117-
if (random) {
118-
neighbors.set(toNodeId(random.getPeerDescriptor()), random)
106+
107+
// Step 4: Fill remaining slots with random contacts
108+
while (targets.size < PARALLEL_HANDSHAKE_COUNT) {
109+
const random = this.options.randomNodeView.getRandom(getExcludedIds())
110+
if (!random) {
111+
break
119112
}
113+
targets.set(toNodeId(random.getPeerDescriptor()), random)
120114
}
121-
return Array.from(neighbors.values()).map((neighbor) => this.createRpcRemote(neighbor.getPeerDescriptor()))
115+
116+
return Array.from(targets.values()).map((neighbor) =>
117+
this.createRpcRemote(neighbor.getPeerDescriptor())
118+
)
122119
}
123120

124121
private async doParallelHandshakes(targets: HandshakeRpcRemote[], excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
@@ -140,29 +137,29 @@ export class Handshaker {
140137

141138
private async selectNewTargetAndHandshake(excludedIds: DhtAddress[]): Promise<DhtAddress[]> {
142139
const exclude = excludedIds.concat(this.options.neighbors.getIds())
143-
const neighbor = this.options.leftNodeView.getFirst(exclude)
140+
const target = this.options.leftNodeView.getFirst(exclude)
144141
?? this.options.rightNodeView.getFirst(exclude)
145142
?? this.options.nearbyNodeView.getFirst(exclude)
146143
?? this.options.randomNodeView.getRandom(exclude)
147-
if (neighbor) {
148-
const accepted = await this.handshakeWithTarget(this.createRpcRemote(neighbor.getPeerDescriptor()))
144+
if (target) {
145+
const accepted = await this.handshakeWithTarget(this.createRpcRemote(target.getPeerDescriptor()))
149146
if (!accepted) {
150-
excludedIds.push(toNodeId(neighbor.getPeerDescriptor()))
147+
excludedIds.push(toNodeId(target.getPeerDescriptor()))
151148
}
152149
}
153150
return excludedIds
154151
}
155152

156-
private async handshakeWithTarget(neighbor: HandshakeRpcRemote, concurrentNodeId?: DhtAddress): Promise<boolean> {
157-
const targetNodeId = toNodeId(neighbor.getPeerDescriptor())
153+
private async handshakeWithTarget(target: HandshakeRpcRemote, concurrentNodeId?: DhtAddress): Promise<boolean> {
154+
const targetNodeId = toNodeId(target.getPeerDescriptor())
158155
this.options.ongoingHandshakes.add(targetNodeId)
159-
const result = await neighbor.handshake(
156+
const result = await target.handshake(
160157
this.options.streamPartId,
161158
this.options.neighbors.getIds(),
162159
concurrentNodeId
163160
)
164161
if (result.accepted) {
165-
this.options.neighbors.add(this.createContentDeliveryRpcRemote(neighbor.getPeerDescriptor()))
162+
this.options.neighbors.add(this.createContentDeliveryRpcRemote(target.getPeerDescriptor()))
166163
}
167164
if (result.interleaveTargetDescriptor) {
168165
await this.handshakeWithInterleaving(result.interleaveTargetDescriptor, targetNodeId)
@@ -172,17 +169,17 @@ export class Handshaker {
172169
}
173170

174171
private async handshakeWithInterleaving(target: PeerDescriptor, remoteNodeId: DhtAddress): Promise<boolean> {
175-
const neighbor = this.createRpcRemote(target)
176-
const targetNodeId = toNodeId(neighbor.getPeerDescriptor())
172+
const remote = this.createRpcRemote(target)
173+
const targetNodeId = toNodeId(remote.getPeerDescriptor())
177174
this.options.ongoingHandshakes.add(targetNodeId)
178-
const result = await neighbor.handshake(
175+
const result = await remote.handshake(
179176
this.options.streamPartId,
180177
this.options.neighbors.getIds(),
181178
undefined,
182179
remoteNodeId
183180
)
184181
if (result.accepted) {
185-
this.options.neighbors.add(this.createContentDeliveryRpcRemote(neighbor.getPeerDescriptor()))
182+
this.options.neighbors.add(this.createContentDeliveryRpcRemote(remote.getPeerDescriptor()))
186183
}
187184
this.options.ongoingHandshakes.delete(targetNodeId)
188185
return result.accepted

0 commit comments

Comments
 (0)