ipfrs-network 0.2.0

Peer-to-peer networking layer with libp2p and QUIC for IPFRS
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
# Peer Discovery Guide

This document explains how peer discovery works in IPFRS Network and how to configure it for different scenarios.

## Overview

IPFRS Network uses multiple discovery mechanisms to find and connect to peers:

1. **Bootstrap Nodes** - Static list of known peers
2. **Kademlia DHT** - Distributed peer discovery
3. **mDNS** - Local network discovery
4. **Peer Exchange** - Learn peers from existing connections

## Discovery Mechanisms

### 1. Bootstrap Nodes

Bootstrap nodes are your entry point to the network.

#### Configuration

```rust
use ipfrs_network::{NetworkConfig, NetworkNode};

let config = NetworkConfig {
    bootstrap_peers: vec![
        ("/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ".to_string()),
        ("/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN".to_string()),
    ],
    ..Default::default()
};

let node = NetworkNode::new(config)?;
```

#### Bootstrap Process

1. **Initial Connection**
   - Node starts and loads bootstrap peer list
   - Attempts to connect to each bootstrap peer
   - Uses exponential backoff for failed connections

2. **Routing Table Population**
   - Once connected, queries bootstrap nodes for nearby peers
   - Fills routing table with discovered peers
   - Continues until routing table is healthy

3. **Health Monitoring**
   - Tracks connection success rate
   - Implements circuit breaker for failing peers
   - Automatically retries after cooldown period

#### Best Practices

- **Multiple Bootstrap Peers**: Use at least 3-5 bootstrap nodes
- **Geographic Distribution**: Choose nodes in different regions
- **Reliability**: Select high-uptime nodes
- **Custom Network**: For private networks, use your own bootstrap nodes

#### Example: Custom Bootstrap Network

```rust
let config = NetworkConfig {
    bootstrap_peers: vec![
        "/ip4/192.168.1.10/tcp/4001/p2p/12D3KooW...".to_string(),
        "/ip4/192.168.1.11/tcp/4001/p2p/12D3KooW...".to_string(),
        "/ip4/192.168.1.12/tcp/4001/p2p/12D3KooW...".to_string(),
    ],
    enable_mdns: true,  // Also discover local peers
    ..Default::default()
};
```

### 2. Kademlia DHT

The DHT provides distributed peer discovery without central authority.

#### How It Works

**Routing Table Structure:**
```
XOR Distance from Local PeerID
├── Bucket 0:  Distance 2^0  to 2^1   (closest)
├── Bucket 1:  Distance 2^1  to 2^2
├── Bucket 2:  Distance 2^2  to 2^3
...
└── Bucket 255: Distance 2^255 to 2^256 (farthest)
```

Each bucket stores up to 20 peers (k-bucket size).

#### Discovery Process

1. **Random Walk**
   ```rust
   // Automatically performed by Kademlia
   // Discovers peers by querying random keys
   ```

2. **FIND_NODE Queries**
   ```rust
   // Find peers close to a specific PeerID
   let peers = node.find_node(target_peer_id).await?;
   ```

3. **Provider Queries**
   ```rust
   // Discover content providers (also discovers peers)
   let providers = node.find_providers(&cid).await?;
   ```

#### Configuration

```rust
use ipfrs_network::KademliaConfig;

let kad_config = KademliaConfig {
    // Number of concurrent queries
    alpha: 3,

    // How many nodes to replicate to
    replication_factor: 20,

    // Query timeout
    query_timeout: Duration::from_secs(60),

    // K-bucket size
    k_bucket_size: 20,
};
```

#### Monitoring DHT Health

```rust
// Check routing table
let info = node.get_routing_table_info();
println!("Routing table has {} peers across {} buckets",
    info.total_peers, info.num_buckets);

// Check DHT health
let health = node.get_dht_health();
match health.status {
    DhtHealthStatus::Healthy => println!("DHT is healthy"),
    DhtHealthStatus::Degraded => println!("DHT is degraded"),
    DhtHealthStatus::Unhealthy => println!("DHT is unhealthy"),
    _ => println!("DHT status unknown"),
}
```

### 3. mDNS (Multicast DNS)

Discover peers on the local network without infrastructure.

#### When to Use mDNS

- **Local Development**: Testing on a single machine or LAN
- **IoT Devices**: Devices on the same network segment
- **Private Networks**: LANs without internet access
- **Fast Discovery**: Sub-second peer discovery locally

#### Configuration

```rust
let config = NetworkConfig {
    enable_mdns: true,  // Enable mDNS discovery
    listen_addrs: vec![
        "/ip4/0.0.0.0/tcp/0".to_string(),  // Listen on all interfaces
    ],
    ..Default::default()
};
```

#### How It Works

1. Node broadcasts service announcement: `_ipfrs._udp.local`
2. Other nodes on the network receive the announcement
3. Nodes automatically connect to discovered peers
4. Works on IPv4 and IPv6

#### Limitations

- **Local Only**: Doesn't work across routers (by design)
- **Network Permission**: May require firewall exceptions
- **Broadcast Storm**: Many peers can cause network congestion
- **Security**: No authentication (trust local network)

#### Troubleshooting mDNS

```bash
# Check if mDNS is working (Linux)
avahi-browse -a

# Check firewall (Linux)
sudo ufw status
sudo ufw allow 5353/udp  # mDNS port

# Check if service is announced
dns-sd -B _ipfrs._udp .
```

### 4. Peer Exchange

Learn about peers from existing connections.

#### Identify Protocol

Every connection exchanges peer information:

```
Connection Established
   ↓
Identify Handshake
   ↓
Exchange:
   - PeerID
   - Listen Addresses
   - Protocol Support
   - Agent Version
```

#### Example

```rust
// This happens automatically
// But you can query peer info:
let peer_info = node.get_peer_info(&peer_id);
if let Some(info) = peer_info {
    println!("Peer addresses: {:?}", info.addrs);
    println!("Protocols: {:?}", info.protocols);
}
```

## Discovery Strategies by Scenario

### Scenario 1: Public Network Node

**Goal**: Join the public IPFS/IPFRS network

```rust
let config = NetworkConfig {
    // Use public bootstrap nodes
    bootstrap_peers: vec![
        "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN".to_string(),
        "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa".to_string(),
    ],
    enable_mdns: false,  // Not useful for public network
    enable_nat_traversal: true,  // Important for home networks
    ..Default::default()
};
```

### Scenario 2: Private Network

**Goal**: Isolated network for organization

```rust
let config = NetworkConfig {
    // Private bootstrap nodes
    bootstrap_peers: vec![
        "/ip4/10.0.0.10/tcp/4001/p2p/12D3KooW...".to_string(),
        "/ip4/10.0.0.11/tcp/4001/p2p/12D3KooW...".to_string(),
    ],
    enable_mdns: true,  // Discover local peers
    enable_nat_traversal: false,  // Not needed in private network
    ..Default::default()
};
```

### Scenario 3: Local Development

**Goal**: Test on a single machine or LAN

```rust
let config = NetworkConfig {
    bootstrap_peers: vec![],  // No bootstrap needed
    enable_mdns: true,  // Primary discovery mechanism
    listen_addrs: vec![
        "/ip4/127.0.0.1/tcp/0".to_string(),  // Localhost
    ],
    ..Default::default()
};
```

### Scenario 4: Edge/IoT Device

**Goal**: Resource-constrained device

```rust
let config = NetworkConfig {
    bootstrap_peers: vec![
        "/ip4/gateway.local/tcp/4001/p2p/12D3KooW...".to_string(),
    ],
    enable_mdns: true,  // Discover local gateway
    connection_limits: ConnectionLimitsConfig {
        max_connections: 10,  // Limit for constrained device
        max_inbound: 5,
        max_outbound: 5,
    },
    ..Default::default()
};
```

### Scenario 5: Mobile Application

**Goal**: Handle network switches gracefully

```rust
let config = NetworkConfig {
    bootstrap_peers: vec![
        "/dns4/mobile-relay.example.com/tcp/443/wss/p2p/12D3KooW...".to_string(),
    ],
    enable_quic: true,  // QUIC supports connection migration
    enable_nat_traversal: true,
    ..Default::default()
};

// Handle network changes
// (future feature - pause/resume)
```

## Advanced Discovery

### Custom Discovery

Implement your own discovery mechanism:

```rust
use ipfrs_network::{NetworkNode, PeerId};

async fn custom_discovery(node: &NetworkNode) {
    // Example: Query central server for peer list
    let peers = fetch_peers_from_server().await;

    for peer in peers {
        if let Err(e) = node.connect(peer.id, peer.addrs).await {
            eprintln!("Failed to connect to {}: {}", peer.id, e);
        }
    }
}
```

### Semantic Peer Discovery

Discover peers with similar content:

```rust
use ipfrs_network::{SemanticDht, NamespaceId, SemanticQuery};

// Find peers hosting similar content
let semantic_dht = SemanticDht::new(config);

// Register namespace
let namespace = SemanticNamespace {
    id: NamespaceId::text(),
    dimension: 768,
    distance_metric: DistanceMetric::Cosine,
    lsh_config: LshConfig::default(),
};
semantic_dht.register_namespace(namespace)?;

// Query for similar content
let query = SemanticQuery {
    embedding: my_embedding,
    namespace: NamespaceId::text(),
    top_k: 10,
    metadata_filter: None,
    timeout: Duration::from_secs(5),
};

let results = semantic_dht.query(query)?;
// Results contain peers with semantically similar content
```

## Monitoring and Debugging

### Check Peer Count

```rust
let stats = node.stats();
println!("Connected peers: {}", stats.connected_peers);
println!("Known peers: {}", stats.known_peers);
```

### List Connected Peers

```rust
let peers = node.get_connected_peers();
for peer_id in peers {
    println!("Connected to: {}", peer_id);
}
```

### Check Bootstrap Status

```rust
let bootstrap_stats = node.get_bootstrap_stats();
println!("Bootstrap attempts: {}", bootstrap_stats.connection_attempts);
println!("Successful: {}", bootstrap_stats.successful_connections);
println!("Failed: {}", bootstrap_stats.failed_connections);
```

### Monitor Discovery Events

```rust
// Events are emitted during discovery
match event {
    NetworkEvent::PeerDiscovered { peer_id, addrs } => {
        println!("Discovered peer {} at {:?}", peer_id, addrs);
    }
    NetworkEvent::ConnectionEstablished { peer_id, endpoint } => {
        println!("Connected to {} via {:?}", peer_id, endpoint);
    }
    _ => {}
}
```

## Performance Tuning

### Optimize for Fast Discovery

```rust
let config = NetworkConfig {
    // More bootstrap peers
    bootstrap_peers: many_bootstrap_peers,

    // Aggressive DHT queries
    kademlia_config: KademliaConfig {
        alpha: 5,  // More concurrent queries
        query_timeout: Duration::from_secs(30),  // Shorter timeout
        ..Default::default()
    },
    ..Default::default()
};
```

### Optimize for Low Bandwidth

```rust
let config = NetworkConfig {
    // Fewer bootstrap peers
    bootstrap_peers: vec![single_reliable_peer],

    // Conservative DHT
    kademlia_config: KademliaConfig {
        alpha: 1,  // Sequential queries
        replication_factor: 5,  // Less replication
        ..Default::default()
    },

    // Disable mDNS (broadcast traffic)
    enable_mdns: false,
    ..Default::default()
};
```

## Common Issues

### Issue: No Peers Discovered

**Symptoms:**
- `connected_peers` stays at 0
- Bootstrap connections fail

**Solutions:**
1. Check network connectivity
   ```bash
   ping 8.8.8.8
   ```

2. Verify bootstrap peer addresses
   ```bash
   nc -zv bootstrap.libp2p.io 4001
   ```

3. Check firewall settings
   ```bash
   sudo ufw status
   sudo ufw allow 4001/tcp
   ```

4. Enable mDNS for local discovery
   ```rust
   config.enable_mdns = true;
   ```

### Issue: Slow Peer Discovery

**Symptoms:**
- Takes minutes to find peers
- DHT queries timeout

**Solutions:**
1. Add more bootstrap peers
2. Increase alpha (concurrent queries)
3. Check network latency
4. Verify NAT traversal is working

### Issue: Too Many Connections

**Symptoms:**
- Resource exhaustion
- Connection churn

**Solutions:**
1. Lower connection limits
   ```rust
   connection_limits: ConnectionLimitsConfig {
       max_connections: 50,  // Reduce from default 100
       ..Default::default()
   }
   ```

2. Enable connection pruning
   ```rust
   // Happens automatically based on connection value
   ```

3. Blacklist problematic peers
   ```rust
   // Use ConnectionManager's ban list
   ```

## Security Considerations

### Bootstrap Node Trust

- Bootstrap nodes see your PeerID and IP
- Use reputable bootstrap nodes
- For sensitive applications, use your own bootstrap nodes

### Discovery Privacy

- mDNS reveals presence on local network
- DHT queries reveal content interests
- Consider using Tor for privacy (future feature)

### Peer Validation

```rust
// Validate peer before connecting
async fn validate_peer(peer_id: &PeerId) -> bool {
    // Check against allowlist/denylist
    // Verify peer reputation
    // Check peer protocols
    true
}
```

## Best Practices

1. **Use Multiple Discovery Methods**
   - Combine bootstrap + DHT + mDNS for reliability

2. **Monitor Discovery Health**
   - Track connected peer count
   - Alert if below threshold

3. **Implement Retry Logic**
   - Bootstrap manager handles this automatically
   - Add application-level retries if needed

4. **Cache Successful Peers**
   - Persistence is handled automatically
   - Load cached peers on startup

5. **Test Discovery Locally**
   - Use mDNS for fast local testing
   - Then test with bootstrap nodes

6. **Document Custom Bootstrap**
   - If running your own network, document bootstrap peers clearly

## References

- [Kademlia DHT Paper]https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf
- [libp2p Peer Discovery]https://docs.libp2p.io/concepts/discovery-routing/overview/
- [mDNS RFC 6762]https://tools.ietf.org/html/rfc6762
- [IPFS Bootstrap]https://docs.ipfs.tech/concepts/nodes/#bootstrap