Arquitectura P2P
Overview
KodeChain implementa una red P2P descentralizada con Kademlia DHT, hole punching ICE, y NAT traversal automático para conectividad global sin servidores centrales.
Componentes Principales
┌─────────────────────────────────────────────────────────┐
│ KodeChain P2P Network │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Discovery Layer │ │
│ │ - UDP Broadcasts │ │
│ │ - Bootstrap Nodes │ │
│ │ - Peer Exchange │ │
│ └──────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Routing Layer (Kademlia DHT) │ │
│ │ - Distributed Hash Table │ │
│ │ - 20 K-Buckets │ │
│ │ - XOR Distance Metric │ │
│ └──────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ NAT Traversal Layer │ │
│ │ - Hole Punching (Pion ICE) │ │
│ │ - STUN/TURN Servers │ │
│ │ - UPnP │ │
│ └──────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Connection Layer │ │
│ │ - TCP Connections │ │
│ │ - UDP Discovery │ │
│ │ - Message Broadcasting │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
Enode Format
Estructura
enode://[node-id]@[ip]:[tcp-port]?discport=[udp-port]
Ejemplo
enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@127.0.0.1:30303?discport=30301
Componentes
- node-id: Hash SHA-256 de la clave pública (64 bytes hex)
- ip: Dirección IP del nodo
- tcp-port: Puerto TCP para conexiones P2P (default: 30303)
- discport: Puerto UDP para discovery (default: 30301)
Discovery Protocol
1. Bootstrap Nodes
bootstrapNodes := []string{
"enode://[id]@seed1.kodechain.io:30303?discport=30301",
"enode://[id]@seed2.kodechain.io:30303?discport=30301",
"enode://[id]@seed3.kodechain.io:30303?discport=30301",
}
2. UDP Announcement
type AnnouncementMessage struct {
Type string `json:"type"`
Data EnodeData `json:"data"`
Timestamp int64 `json:"timestamp"`
Signature string `json:"signature"`
}
type EnodeData struct {
ID string `json:"id"`
IP string `json:"ip"`
Ports PortConfig `json:"ports"`
}
3. Peer Exchange
// Solicitar peers
{
"type": "peer_request",
"requested_count": 20
}
// Respuesta con peers
{
"type": "peer_response",
"peers": [
"enode://...",
"enode://...",
...
]
}
Kademlia DHT
Routing Table
type RoutingTable struct {
buckets [20]*KBucket // 20 buckets (0-255 distance)
localNode *Node
bucketSize int // k = 16
}
type KBucket struct {
nodes []*Node // Max 16 nodes
lastUpdate time.Time
mutex sync.RWMutex
}
XOR Distance Metric
func distance(node1, node2 string) *big.Int {
id1 := new(big.Int).SetBytes([]byte(node1))
id2 := new(big.Int).SetBytes([]byte(node2))
return new(big.Int).Xor(id1, id2)
}
Bucket Selection
Node ID: 1010101...
Target: 1110101...
XOR: 0100000...
^
First different bit at position 1
→ Use Bucket 1
Operations
1. FindNode
func (rt *RoutingTable) FindNode(targetID string) []*Node {
// 1. Calcular distancia XOR
distance := distance(rt.localNode.ID, targetID)
// 2. Seleccionar bucket apropiado
bucketIndex := distance.BitLen() - 1
// 3. Retornar k nodos más cercanos (k=16)
return rt.buckets[bucketIndex].GetClosestNodes(targetID, 16)
}
2. Store Value
func (rt *RoutingTable) Store(key string, value []byte) error {
// 1. Encontrar nodos responsables
nodes := rt.FindNode(key)
// 2. Almacenar en k nodos más cercanos
for _, node := range nodes {
node.Store(key, value)
}
return nil
}
Connection Management
Connection Manager
type ConnectionManager struct {
connections map[string]*Connection
maxPeers int // Default: 50
mutex sync.RWMutex
}
type Connection struct {
Enode string
Conn net.Conn
LastSeen time.Time
BytesSent uint64
BytesRecv uint64
IsOutbound bool
}
Lifecycle
1. Discovery
↓ Encontrar peer via DHT
2. NAT Traversal
↓ Hole punching si es necesario
3. TCP Handshake
↓ Establecer conexión
4. Protocol Handshake
↓ Intercambiar info de protocolo
5. Active Connection
↓ Mantener conexión activa
6. Heartbeat
↓ Ping cada 30 segundos
7. Disconnect
└── Por timeout, error, o cierre
Message Broadcasting
Broadcast Types
1. Flood Broadcast
func (cm *ConnectionManager) Broadcast(message Message) {
// Enviar a todos los peers conectados
for _, conn := range cm.connections {
go conn.Send(message)
}
}
2. Gossip Protocol
func (cm *ConnectionManager) Gossip(message Message) {
// Enviar a subset aleatorio (30%)
peerCount := len(cm.connections)
gossipCount := int(float64(peerCount) * 0.3)
randomPeers := selectRandomPeers(gossipCount)
for _, peer := range randomPeers {
peer.Send(message)
}
}
Message Types
const (
MsgAnnouncement = "announcement"
MsgPeerRequest = "peer_request"
MsgPeerResponse = "peer_response"
MsgBlock = "block"
MsgTransaction = "transaction"
MsgSync = "sync"
MsgHeartbeat = "heartbeat"
)
Hole Punching (ICE)
Ver documentación detallada: Hole Punching ICE
Flujo Básico
Peer A (NAT) Peer B (NAT)
│ │
├─ 1. Gather Candidates │
│ - Host (192.168.1.100) │
│ - Server Reflexive (STUN) │
│ - Relay (TURN) │
│ │
├─ 2. Exchange Candidates ─────────┤
│ │
│ ┌─ 3. Connectivity Checks ─┐ │
│ │ - Try all combinations │ │
│ │ - Select best pair │ │
│ └───────────────────────────┘ │
│ │
└─ 4. Direct Connection ───────────┘
Network Protocols
TCP Protocol (P2P)
Puerto: 30303
Uso: Conexiones P2P persistentes
Flow: Bidireccional
UDP Protocol (Discovery)
Puerto: 30301
Uso: Discovery broadcasts
Flow: Multicast
HTTP Protocol (API)
Puerto: 8545
Uso: REST API, WebSocket
Flow: Cliente → Servidor
Peer Selection Strategy
Trust Score
type PeerTrustScore struct {
Uptime float64 // 0-1
ResponseTime int64 // ms
FailedRequests int
SuccessRate float64 // 0-1
LastSeen time.Time
}
func calculateTrustScore(peer *Peer) float64 {
uptime := peer.Uptime / totalTime
responseScore := 1.0 - (peer.ResponseTime / maxResponseTime)
successRate := peer.SuccessfulRequests / peer.TotalRequests
return (uptime * 0.4) +
(responseScore * 0.3) +
(successRate * 0.3)
}
Peer Ranking
High Priority:
├── Bootstrap nodes
├── Validators
└── High trust score peers
Medium Priority:
├── Normal peers
└── Medium trust score
Low Priority:
├── New peers
├── Low trust score
└── Frequently failing
NAT Types y Soluciones
| NAT Type | Descripción | Solución |
|---|---|---|
| Full Cone | Un mapping para todos | Directo |
| Restricted | Por IP source | Hole Punching |
| Port Restricted | Por IP y port | Hole Punching |
| Symmetric | Mapping por destino | TURN Relay |
Performance Optimizations
1. Connection Pooling
// Mantener pool de conexiones reutilizables
connectionPool := &sync.Pool{
New: func() interface{} {
return &Connection{
Buffer: make([]byte, 65536),
}
},
}
2. Message Batching
// Agrupar mensajes pequeños
batcher := NewMessageBatcher(100 * time.Millisecond)
batcher.Add(message1)
batcher.Add(message2)
// Flush automático cada 100ms
3. Compression
// Comprimir mensajes > 1KB
if len(message) > 1024 {
compressed := compress(message)
send(compressed)
}
Monitoreo de Red
Métricas Clave
# Ver peers conectados
curl http://localhost:8545/api/network/peers
# Estadísticas de red
curl http://localhost:8545/api/network/stats
# Latencia a peers
curl http://localhost:8545/api/network/latency
Estadísticas
{
"total_peers": 48,
"inbound": 25,
"outbound": 23,
"bytes_sent": 125000000,
"bytes_received": 98000000,
"messages_per_second": 150,
"average_latency_ms": 45
}
Troubleshooting
No peers conectados
# 1. Verificar puertos abiertos
netstat -tuln | grep -E '30303|30301'
# 2. Verificar bootstrap nodes
curl http://localhost:8545/api/network/bootstrap
# 3. Forzar discovery
curl -X POST http://localhost:8545/api/network/rediscover
Alta latencia
# Ver latencia por peer
curl http://localhost:8545/api/network/peers?sort=latency
# Desconectar peers lentos
curl -X POST http://localhost:8545/api/network/disconnect/[peer-id]
Próximos Pasos
- Hole Punching ICE - NAT traversal avanzado
- NAT Traversal - Soluciones de conectividad
- Kademlia DHT - Routing distribuido
- Network Protocols - Protocolos detallados
Red P2P descentralizada y resiliente 🌐