docs: I2P-EMBEDDED-ARCHITECTURE.md
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
# I2P Embedded Architecture (Level 3)
|
||||
|
||||
**Date:** 2026-06-27
|
||||
**Status:** ✅ IMPLEMENTED & WORKING
|
||||
|
||||
---
|
||||
|
||||
## What This Is
|
||||
|
||||
Triangles now runs **two embedded anonymity networks simultaneously**:
|
||||
|
||||
1. **Tor** — Every node is a .onion hidden service (existing, unchanged)
|
||||
2. **I2P** — Every node is a .b32.i2p destination (new)
|
||||
|
||||
Both routers run **in-process** as static libraries. No external dependencies, no separate daemons to install.
|
||||
|
||||
### What I2P Adds Over Tor-Only
|
||||
|
||||
| Property | Tor | I2P |
|
||||
|----------|-----|-----|
|
||||
| Routing | Onion (3-hop circuits) | Garlic (variable-hop tunnels) |
|
||||
| Directory | Centralized authorities | Distributed floodfills |
|
||||
| Service discovery | Hidden service descriptors | Network database (KadDHT) |
|
||||
| Designed for | Exit to clearnet | Peer-to-peer services |
|
||||
| Peer correlation resistance | Moderate | Strong (ephemeral tunnels) |
|
||||
|
||||
I2P was designed from the ground up for **peer-to-peer anonymous services** — exactly what a cryptocurrency P2P network needs. Tor's hidden services work, but Tor is optimized for anonymous web browsing (exit traffic). I2P's garlic routing, distributed network database, and short-lived tunnels make it inherently better suited for P2P mesh communication.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
### Dual-Network Routing
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ trianglesd (process) │
|
||||
│ │
|
||||
│ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ libtor │ │ libi2pd │ │
|
||||
│ │ (Tor) │ │ (I2P) │ │
|
||||
│ └────┬────┘ └────┬────┘ │
|
||||
│ │ │ │
|
||||
.onion peers ─────┼───────┘ │ │
|
||||
│ SOCKS 19099 │ │
|
||||
│ │ │
|
||||
.b32.i2p peers ───┼──────────────────────┘ │
|
||||
│ SOCKS 19100 │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Traffic Flow
|
||||
|
||||
| Destination | Route | Proxy |
|
||||
|-------------|-------|-------|
|
||||
| `*.onion` | Tor SOCKS5 → Tor circuit → hidden service | 127.0.0.1:19099 |
|
||||
| `*.b32.i2p` | I2P SOCKS5 → I2P tunnel → destination | 127.0.0.1:19100 |
|
||||
| Clearnet (IPv4/IPv6) | **BLOCKED** | — |
|
||||
|
||||
The routing decision happens in `ConnectSocketByName()` (netbase.cpp):
|
||||
- `.b32.i2p` suffix → I2P SOCKS proxy (NET_I2P)
|
||||
- Everything else → Tor name proxy (SetNameProxy)
|
||||
|
||||
---
|
||||
|
||||
## Implementation
|
||||
|
||||
### Files Added
|
||||
|
||||
```
|
||||
src/i2p/
|
||||
├── i2pd-src/ # PurpleI2P/i2pd git submodule
|
||||
├── i2p_embedded.h # CI2PEmbedded class declaration
|
||||
├── i2p_embedded.cpp # Embedded router start/stop logic
|
||||
├── i2pseed.h # Hardcoded .b32.i2p seed nodes
|
||||
└── build-libi2pd.sh # Static library build script
|
||||
```
|
||||
|
||||
### Files Modified
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `CMakeLists.txt` | `USE_I2P_EMBEDDED` option + config summary |
|
||||
| `src/CMakeLists.txt` | I2P source, includes, library linking |
|
||||
| `src/init.cpp` | I2P startup (after Tor), shutdown, CLI flags |
|
||||
| `src/net.cpp` | Allow `.b32.i2p` in `ConnectNode()` and seed parser |
|
||||
| `src/netbase.cpp` | I2P SOCKS routing, fixed `.b32.i2p` address parsing |
|
||||
|
||||
### CI2PEmbedded Class
|
||||
|
||||
Singleton pattern (mirrors `CTorEmbedded`):
|
||||
|
||||
```cpp
|
||||
class CI2PEmbedded {
|
||||
bool Start(int socksPort, int samPort, int serverPort);
|
||||
void Stop();
|
||||
bool IsRunning() const;
|
||||
std::string GetSocksProxy() const; // "127.0.0.1:19100"
|
||||
std::string GetI2PAddress() const; // .b32.i2p destination
|
||||
};
|
||||
```
|
||||
|
||||
### Startup Sequence (init.cpp)
|
||||
|
||||
```
|
||||
1. StartEmbeddedTor() → Tor SOCKS on 19099
|
||||
2. TOR-NATIVE MODE → all traffic forced through Tor
|
||||
3. StartEmbeddedI2P() → i2pd SOCKS on 19100
|
||||
4. I2P-NATIVE MODE → .b32.i2p routed through i2pd
|
||||
5. Dual-network anonymity → Tor + I2P co-equal
|
||||
```
|
||||
|
||||
If I2P fails to start, the daemon continues in Tor-only mode (non-fatal).
|
||||
|
||||
### How i2pd Integrates
|
||||
|
||||
i2pd provides a C++ API (`libi2pd/api.h`) for in-process embedding:
|
||||
|
||||
```cpp
|
||||
i2p::api::InitI2P(argc, argv, "triangles-i2pd");
|
||||
i2p::api::StartI2P(logStream);
|
||||
i2p::client::context.Start(); // SAM, SOCKS, tunnels
|
||||
```
|
||||
|
||||
The auto-generated `i2pd.conf` enables:
|
||||
- SOCKS proxy on 19100 (for outbound .b32.i2p)
|
||||
- SAM bridge on 7656 (for future SAM v3 protocol)
|
||||
- Server tunnel in `tunnels.conf` (I2P hidden service)
|
||||
|
||||
The `tunnels.conf` is written before `Start()`:
|
||||
```ini
|
||||
[triangles-p2p]
|
||||
type = server
|
||||
host = 127.0.0.1
|
||||
port = <P2P_PORT>
|
||||
keys = triangles-p2p-keys.dat
|
||||
inbound.length = 3
|
||||
outbound.length = 3
|
||||
```
|
||||
|
||||
This creates a persistent `.b32.i2p` destination that survives restarts.
|
||||
|
||||
---
|
||||
|
||||
## Build Instructions
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Same as existing Tor build + Boost (already required).
|
||||
|
||||
### Build with I2P
|
||||
|
||||
```bash
|
||||
# 1. Initialize the i2pd submodule
|
||||
git submodule update --init --recursive src/i2p/i2pd-src
|
||||
|
||||
# 2. Build i2pd static libraries
|
||||
cd src/i2p && bash build-libi2pd.sh
|
||||
|
||||
# 3. Configure and build Triangles
|
||||
mkdir build && cd build
|
||||
cmake -G Ninja -DUSE_I2P_EMBEDDED=ON ..
|
||||
ninja trianglesd
|
||||
```
|
||||
|
||||
### Build without I2P (Tor-only, existing behavior)
|
||||
|
||||
```bash
|
||||
cmake -G Ninja .. # USE_I2P_EMBEDDED defaults to OFF
|
||||
ninja trianglesd
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CLI Flags
|
||||
|
||||
| Flag | Default | Description |
|
||||
|------|---------|-------------|
|
||||
| `-i2p` | `1` | Enable embedded I2P router |
|
||||
| `-i2psocks=<port>` | `19100` | I2P SOCKS proxy port |
|
||||
| `-i2psam=<port>` | `7656` | I2P SAM bridge port |
|
||||
| `-i2phsport=<port>` | P2P port | I2P server tunnel forward port |
|
||||
|
||||
---
|
||||
|
||||
## Testing Verification
|
||||
|
||||
### Expected Startup Output
|
||||
|
||||
```
|
||||
Embedded I2P: starting i2pd router...
|
||||
Embedded I2P: server tunnel configured on port 24112
|
||||
...
|
||||
Clients: New private keys file .../triangles-p2p-keys.dat for <b32>.b32.i2p created
|
||||
Clients: 1 I2P server tunnels created
|
||||
Embedded I2P: SOCKS proxy at 127.0.0.1:19100, SAM at 127.0.0.1:7656
|
||||
...
|
||||
I2P-NATIVE MODE: I2P router running
|
||||
SOCKS proxy at 127.0.0.1:19100 for .b32.i2p connections
|
||||
Dual-network anonymity: Tor (.onion) + I2P (.b32.i2p)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Seed Node Deployment
|
||||
|
||||
To deploy an I2P seed node:
|
||||
|
||||
1. Build with `-DUSE_I2P_EMBEDDED=ON`
|
||||
2. Start the daemon — it auto-generates a `.b32.i2p` destination
|
||||
3. Read the address from the log: `grep "b32.i2p" debug.log`
|
||||
4. Add the address to `src/i2p/i2pseed.h`
|
||||
5. Add the address to `seeds.cryptographic-triangles.org/i2p-seeds.txt`
|
||||
|
||||
The destination keys persist in `<datadir>/i2p_data/triangles-p2p-keys.dat`.
|
||||
|
||||
---
|
||||
|
||||
## Comparison to Other Projects
|
||||
|
||||
| Project | Tor | I2P | Embedded | Dual-Network |
|
||||
|---------|-----|-----|----------|-------------|
|
||||
| **Triangles** | ✅ Embedded | ✅ Embedded | Both in-process | ✅ |
|
||||
| Bitcoin Core | Optional | Optional (SAM) | No | No |
|
||||
| Monero | Optional | No | No | No |
|
||||
| Kovri (Monero I2P) | N/A | Planned | Planned | No |
|
||||
|
||||
Triangles is the only cryptocurrency with **both** Tor and I2P embedded as in-process routers.
|
||||
|
||||
---
|
||||
|
||||
## Future Work
|
||||
|
||||
- **I2P seed nodes:** Deploy stable .b32.i2p seeds (parallel to onion seeds)
|
||||
- **SAM v3 direct:** Use SAM bridge for native I2P streaming (bypass SOCKS overhead)
|
||||
- **I2P address in RPC:** Expose `.b32.i2p` address via `getnetworkinfo`
|
||||
- **Cross-network bridging:** Allow Tor nodes to discover I2P peers and vice versa
|
||||
Reference in New Issue
Block a user