You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/app/blog/lets-write-a-dht-3/page.mdx
+14-14Lines changed: 14 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ export const post = {
7
7
date: '2025-09-20',
8
8
title: 'A DHT for iroh',
9
9
description:
10
-
"Let's write a DHT for iroh - part 3",
10
+
"Let's write a DHT for iroh - tests",
11
11
}
12
12
13
13
exportconst metadata = {
@@ -136,27 +136,27 @@ We are using the [textplots] crate to get nice plots in the console, with some o
136
136
```
137
137
138
138
<divclassName="not-prose">
139
-
<imgsrc="/blog/lets-write-a-dht/perfect_routing_tables_1k_-_histogram_-_commonality_with_perfect_set_of_20_ids.png"width={1000}alt="Removal of 100 nodes" />
139
+
<imgsrc="/blog/lets-write-a-dht-3/perfect_routing_tables_1k_-_histogram_-_commonality_with_perfect_set_of_20_ids.png"width={1000}alt="Removal of 100 nodes" />
140
140
</div>
141
141
142
142
So far, so good. We get a 100% overlap with the perfect set of ids.
143
143
144
144
<divclassName="not-prose">
145
-
<imgsrc="/blog/lets-write-a-dht/perfect_routing_tables_1k_-_storage_usage_per_node.png"width={1000}alt="Removal of 100 nodes" />
145
+
<imgsrc="/blog/lets-write-a-dht-3/perfect_routing_tables_1k_-_storage_usage_per_node.png"width={1000}alt="Removal of 100 nodes" />
146
146
</div>
147
147
148
148
<divclassName="not-prose">
149
-
<imgsrc="/blog/lets-write-a-dht/perfect_routing_tables_1k_-_histogram_-_storage_usage_per_node.png"width={1000}alt="Removal of 100 nodes" />
149
+
<imgsrc="/blog/lets-write-a-dht-3/perfect_routing_tables_1k_-_histogram_-_storage_usage_per_node.png"width={1000}alt="Removal of 100 nodes" />
150
150
</div>
151
151
152
152
Data is evenly distributed over the DHT nodes. The histogram also looks reasonable. Since we have 100% overlap with the perfect set of nodes, the little bump at the end is just a blip, provided or XOR metric works.
153
153
154
154
<divclassName="not-prose">
155
-
<imgsrc="/blog/lets-write-a-dht/perfect_routing_tables_1k_-_routing_table_size_per_node.png"width={1000}alt="Removal of 100 nodes" />
155
+
<imgsrc="/blog/lets-write-a-dht-3/perfect_routing_tables_1k_-_routing_table_size_per_node.png"width={1000}alt="Removal of 100 nodes" />
156
156
</div>
157
157
158
158
<divclassName="not-prose">
159
-
<imgsrc="/blog/lets-write-a-dht/perfect_routing_tables_1k_-_histogram_-_routing_table_size_per_node.png"width={1000}alt="Removal of 100 nodes" />
159
+
<imgsrc="/blog/lets-write-a-dht-3/perfect_routing_tables_1k_-_histogram_-_routing_table_size_per_node.png"width={1000}alt="Removal of 100 nodes" />
160
160
</div>
161
161
162
162
All routing tables have roughly the same size. Not surprising since we have initialized them all with a randomized sequence of all node ids.
@@ -176,21 +176,21 @@ So let's see how bad it is.
176
176
```
177
177
178
178
<divclassName="not-prose">
179
-
<imgsrc="/blog/lets-write-a-dht/just_bootstrap_1k_-_histogram_-_commonality_with_perfect_set_of_20_ids.png"width={1000}alt="Removal of 100 nodes" />
179
+
<imgsrc="/blog/lets-write-a-dht-3/just_bootstrap_1k_-_histogram_-_commonality_with_perfect_set_of_20_ids.png"width={1000}alt="Removal of 100 nodes" />
180
180
</div>
181
181
182
182
Pretty bad. The routing gives between 0 and 11 correct nodes. Note that even with this very suboptimal routing table setup the lookup would work 100% of the time if you use the same node for storage and retrieval, since it always gives the same wrong answer. If you were to use different nodes, there is still some decent chance of an overlap.
183
183
184
184
Let's look at more stats:
185
185
186
186
<divclassName="not-prose">
187
-
<imgsrc="/blog/lets-write-a-dht/just_bootstrap_1k_-_storage_usage_per_node.png"width={1000}alt="Removal of 100 nodes" />
187
+
<imgsrc="/blog/lets-write-a-dht-3/just_bootstrap_1k_-_storage_usage_per_node.png"width={1000}alt="Removal of 100 nodes" />
188
188
</div>
189
189
190
190
We interact with the node with index 500, and since each node only knows about nodes further right on the ring, the nodes to the left of our initial node are not used at all.
191
191
192
192
<divclassName="not-prose">
193
-
<imgsrc="/blog/lets-write-a-dht/just_bootstrap_1k_-_routing_table_size_per_node.png"width={1000}alt="Removal of 100 nodes" />
193
+
<imgsrc="/blog/lets-write-a-dht-3/just_bootstrap_1k_-_routing_table_size_per_node.png"width={1000}alt="Removal of 100 nodes" />
194
194
</div>
195
195
196
196
We have only interacted with node 500, so it has learned a bit about the network. But the other nodes only have the initial 20 bootstrap nodes. We have run all nodes in transient mode, so they don't learn about other nodes unless they actively perform a query, which in this case only node 500 has done.
@@ -206,19 +206,19 @@ cargo test --release self_lookup_strategy -- --nocapture
206
206
Initially things look just as bad as with just bootstrap nodes:
207
207
208
208
<divclassName="not-prose">
209
-
<imgsrc="/blog/lets-write-a-dht/self_lookup_strategy-0_-_histogram_-_commonality_with_perfect_set_of_20_ids.png"width={1000}alt="Removal of 100 nodes" />
209
+
<imgsrc="/blog/lets-write-a-dht-3/self_lookup_strategy-0_-_histogram_-_commonality_with_perfect_set_of_20_ids.png"width={1000}alt="Removal of 100 nodes" />
210
210
</div>
211
211
212
212
But after just a few random lookups, routing results are close to perfect for this small DHT
213
213
214
214
<divclassName="not-prose">
215
-
<imgsrc="/blog/lets-write-a-dht/self_lookup_strategy-9_-_histogram_-_commonality_with_perfect_set_of_20_ids.png"width={1000}alt="Removal of 100 nodes" />
215
+
<imgsrc="/blog/lets-write-a-dht-3/self_lookup_strategy-9_-_histogram_-_commonality_with_perfect_set_of_20_ids.png"width={1000}alt="Removal of 100 nodes" />
216
216
</div>
217
217
218
218
The node that is being probed can still be clearly seen, but after just a few self lookups at least all nodes have reasonably sized routing tables:
219
219
220
220
<divclassName="not-prose">
221
-
<imgsrc="/blog/lets-write-a-dht/self_lookup_strategy-9_-_routing_table_size_per_node.png"width={1000}alt="Removal of 100 nodes" />
221
+
<imgsrc="/blog/lets-write-a-dht-3/self_lookup_strategy-9_-_routing_table_size_per_node.png"width={1000}alt="Removal of 100 nodes" />
222
222
</div>
223
223
224
224
## How big can you go?
@@ -291,7 +291,7 @@ But now we need to additionally show evolution of this bitmap over time. Fortuna
291
291
Here it is:
292
292
293
293
<divclassName="not-prose">
294
-
<imgsrc="/blog/lets-write-a-dht/partition_1k.gif"width={1000}height={1000}alt="Addition of 100 partitioned nodes" />
294
+
<imgsrc="/blog/lets-write-a-dht-3/partition_1k.gif"width={1000}height={1000}alt="Addition of 100 partitioned nodes" />
295
295
</div>
296
296
297
297
The big diagonal bar is the bootstrap nodes. As you can see they wrap around at 900. The lowest 100 rows are the routing tables of the initially disconnected nodes, and the rightmost 100 pixels is the knowledge of the connected nodes of the initially disconnected rows. Both are initially empty. As soon as the 100 partitioned nodes are connected, the 100 new nodes very quickly learn about the main swarm, and the main swarm somewhat more slowly learns about the 100 new nodes. So everything works as designed.
<imgsrc="/blog/lets-write-a-dht/remove_1k.gif"width={1000}height={1000}alt="Removal of 100 nodes" />
339
+
<imgsrc="/blog/lets-write-a-dht-3/remove_1k.gif"width={1000}height={1000}alt="Removal of 100 nodes" />
340
340
</div>
341
341
342
342
You can clearly see all nodes quickly forgetting about the dead nodes (last 100 pixels in each row). So removal of dead nodes works in principle. You could of course accelerate this by explicitly pinging all routing table entries in regular intervals, but that would be costly, and only gradually forgetting about dead nodes might even have some advantages - there is a grace period where nodes could come back.
0 commit comments