Skip to content

aratan/dbp2p

Repository files navigation

Sincronización de Datos en DBP2P

DBP2P es una base de datos NoSQL descentralizada que permite sincronizar datos entre múltiples nodos de forma automática. Este documento explica cómo funciona la sincronización y cómo utilizarla.

Cómo Funciona la Sincronización

La sincronización en DBP2P utiliza el protocolo libp2p para comunicarse entre nodos y mantener los datos consistentes. Cuando se realiza una operación CRUD (Crear, Leer, Actualizar, Eliminar) en un nodo, esta operación se propaga automáticamente a todos los demás nodos conectados a la red P2P.

Características Principales

  1. Sincronización Automática: Todas las operaciones CRUD se sincronizan automáticamente.
  2. Descubrimiento de Nodos: Los nodos se descubren automáticamente mediante mDNS (en redes locales) y DHT (en Internet).
  3. Resolución de Conflictos: En caso de conflictos, se utiliza una estrategia de "último en escribir gana".
  4. Sincronización Completa: Es posible sincronizar manualmente todos los documentos con el comando sync.

Configuración de la Sincronización

La sincronización está habilitada por defecto. Puedes configurarla en el archivo config.yaml:

network:
  libp2p:
    listen_addresses:
      - "/ip4/0.0.0.0/tcp/4001"
      - "/ip4/0.0.0.0/udp/4001/quic"
    bootstrap_peers:
      - "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ"
  mdns:
    enabled: true
    service_name: "dbp2p"
    interval: 10
  dht:
    enabled: true
    mode: "server"
    bootstrap_interval: 300

Parámetros de Configuración

  • listen_addresses: Direcciones en las que el nodo escucha conexiones entrantes.
  • bootstrap_peers: Nodos de arranque para conectarse a la red P2P.
  • mdns.enabled: Habilita o deshabilita el descubrimiento de nodos mediante mDNS (para redes locales).
  • mdns.service_name: Nombre del servicio mDNS.
  • mdns.interval: Intervalo de anuncio mDNS en segundos.
  • dht.enabled: Habilita o deshabilita el DHT (Distributed Hash Table) para descubrimiento de nodos en Internet.
  • dht.mode: Modo de operación del DHT ("server" o "client").
  • dht.bootstrap_interval: Intervalo de conexión a nodos de arranque en segundos.

Uso de la Sincronización

Sincronización Automática

La sincronización automática está habilitada por defecto. Cuando creas, actualizas o eliminas un documento, la operación se propaga automáticamente a todos los nodos conectados.

Sincronización Manual

Puedes sincronizar manualmente todos los documentos con el comando sync en la interfaz de línea de comandos:

> sync
Sincronizando todos los documentos...
Sincronización completada

Verificación de Nodos Conectados

Para verificar los nodos conectados, puedes usar la API REST:

GET /api/network/peers

Respuesta:

{
  "peers": [
    "12D3KooWRzPQ8NFTXzKAEH3fRmmBZGgbqxYRdKtxVCPnkd8sDMxH",
    "12D3KooWMHVqLUNpqXvQMPvbQhS7uaiCyWsiKXMQNL4RdpgMKSJf"
  ],
  "count": 2
}

Solución de Problemas

Los datos no se sincronizan

  1. Verificar conectividad P2P: Asegúrate de que los nodos estén conectados entre sí. Puedes verificar los nodos conectados con la API REST.
  2. Verificar configuración de red: Asegúrate de que mDNS y/o DHT estén habilitados y configurados correctamente.
  3. Verificar firewalls: Asegúrate de que los puertos necesarios (por defecto, 4001) estén abiertos en tu firewall.
  4. Sincronización manual: Intenta sincronizar manualmente con el comando sync.

Conflictos de datos

En caso de conflictos (cuando dos nodos modifican el mismo documento), DBP2P utiliza una estrategia de "último en escribir gana". Esto significa que la última modificación recibida será la que prevalezca.

Ejemplos de Uso

Ejemplo 1: Sincronización entre dos nodos en la misma red local

  1. Inicia el primer nodo:

    ./dbp2p.exe
    
  2. Inicia el segundo nodo en otra máquina:

    ./dbp2p.exe
    
  3. Los nodos se descubrirán automáticamente mediante mDNS y comenzarán a sincronizar datos.

Ejemplo 2: Sincronización entre nodos en diferentes redes

  1. Configura los nodos con los mismos nodos de arranque en config.yaml:

    network:
      libp2p:
        bootstrap_peers:
          - "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ"
  2. Inicia los nodos:

    ./dbp2p.exe
    
  3. Los nodos se conectarán a los nodos de arranque y se descubrirán entre sí a través del DHT.

Limitaciones

  • La sincronización requiere que los nodos estén conectados a la red P2P.
  • En redes con NAT, es posible que necesites configurar el reenvío de puertos para permitir conexiones entrantes.
  • La estrategia de resolución de conflictos "último en escribir gana" puede no ser adecuada para todos los casos de uso.

Arquitectura del Proyecto

classDiagram
    class Main {
        +main()
        +runCLI()
    }

    class Config {
        +API.Port int
        +WebSocket.Port int
        +Network libp2p config
        +Auth.JWT.Secret string
        +LoadConfig(path) *Config
        +GetConfig() *Config
    }

    class Document {
        -id string
        -collection string
        -data map
        -version int
        +NewDocument(collection, data) *Document
        +Update(data)
        +ToJSON() []byte
        +MatchesQuery(query) bool
    }

    class Database {
        -documents map[string]*Document
        -persistence *PersistenceManager
        -sync *DBSync
        -anonymizer *Anonymizer
        +CreateDocument(collection, data) *Document
        +GetDocument(id) *Document
        +UpdateDocument(id, data) *Document
        +DeleteDocument(id) error
        +QueryDocuments(collection, query) []*Document
        +GetAllDocuments(collection) []*Document
        +CreateBackup() string
        +RestoreFromBackup(name) error
    }

    class PersistenceManager {
        -dataDir string
        -encryptionKey string
        +SaveDocument(doc) error
        +UpdateDocument(doc) error
        +DeleteDocument(collection, id) error
        +LoadAllDocuments() map[string]*Document
        +CreateBackup() string
        +RestoreFromBackup(name) error
    }

    class DBSync {
        -pubSub *pubsub.PubSub
        +PublishCreate(doc) error
        +PublishUpdate(doc) error
        +PublishDelete(docID) error
        +SyncAllDocuments() error
        +listenForUpdates()
    }

    class TransactionLogger {
        +LogOperation(op, docID, doc) error
        +ReadTransactions() []Transaction
    }

    class AuthManager {
        -users map[string]*User
        -roles map[string]*Role
        -keyManager *KeyManager
        +CreateUser(opts) *User
        +GetUserByUsername(name) *User
        +CreateAPIKey(userID, name, days) SecureAPIKey
        +CheckUserPermission(userID, resource, action) bool
    }

    class KeyManager {
        -encryptionKey []byte
        +GenerateSecureAPIKey(name, days, perms) SecureAPIKey
        +EncryptToken(token) string
        +DecryptToken(encrypted) string
    }

    class User {
        +ID string
        +Username string
        +PasswordHash string
        +Roles []string
        +GenerateAPIKey(name, days) APIKey
        +VerifyAPIKey(token) bool
    }

    class APIServer {
        -database *Database
        -authManager *AuthManager
        -binaryManager *BinaryManager
        -auditLogger *AuditLogger
        +Start(port) error
        +setupRoutes()
        +authMiddleware() Handler
        +rateLimitMiddleware() Handler
    }

    class WSServer {
        -database *Database
        -authManager *AuthManager
        -binaryManager *BinaryManager
        -clients map[string]*Client
        +ServeWS(port) error
        +PublishEvent(event, collection, docID, doc)
    }

    class Client {
        -conn *websocket.Conn
        -user *User
        +readPump()
        +writePump()
        +handleQuery(payload)
        +handleCreate(payload)
        +handleUpdate(payload)
        +handleDelete(payload)
        +handleBinaryUpload(data)
    }

    class Node {
        -host host.Host
        -dht *DHTService
        -mdns *MDNSService
        -sync *DBSync
        +NewNode(ctx) *Node
        +GetPeers() []string
        +SetDatabase(db) error
    }

    class BinaryManager {
        +StoreBinary(id, data) error
        +GetBinary(id) []byte
        +DeleteBinary(id) error
    }

    class Anonymizer {
        +AnonymizeDocumentData(data, rules)
    }

    class RateLimiter {
        +AllowRequest(key) bool
    }

    class SecureConfigManager {
        +EncryptValue(plaintext) string
        +DecryptValue(encrypted) string
    }

    class SecureBackup {
        +SetSecureBackupKey(key)
        +EncryptBackup(data) []byte
        +DecryptBackup(data) []byte
    }

    class AuditLogger {
        +LogLogin(username, success)
        +LogSystemEvent(event, details)
        +LogDocumentAccess(user, docID, action)
    }

    class SanitizeUtil {
        +SanitizeCollectionName(name) string$
        +SanitizeID(id) string$
    }

    %% Relationships
    Main --> Config : carga
    Main --> APIServer : inicia
    Main --> WSServer : inicia
    Main --> Node : inicia
    Main --> Database : crea

    Database --> Document : gestiona *
    Database --> PersistenceManager : persiste
    Database --> DBSync : sincroniza
    Database --> TransactionLogger : registra
    Database --> Anonymizer : anonimiza

    Node --> DBSync : contiene
    Node ..> MDNSService : inicia
    Node ..> DHTService : inicia

    APIServer --> Database : consulta
    APIServer --> AuthManager : autentica
    APIServer --> BinaryManager : archivos
    APIServer --> AuditLogger : audita
    APIServer --> RateLimiter : limita

    WSServer --> Database : consulta
    WSServer --> AuthManager : autentica
    WSServer --> BinaryManager : archivos
    WSServer --> Client : maneja *

    Client ..> BinaryManager : sube/baja

    AuthManager --> KeyManager : encripta
    AuthManager --> User : gestiona *
    AuthManager --> Role : gestiona *

    Database --> SecureBackup : encripta backups

    SecureConfigManager ..> Config : encripta valores
    SanitizeUtil ..> APIServer : sanitiza entrada
    SanitizeUtil ..> WSServer : sanitiza entrada

    note for APIServer "REST API :8090\nEndpoints: /api/auth, /api/collections, /api/users, /api/backups"
    note for WSServer "WebSocket :8100\nEventos: create, update, delete, binary"
    note for Node "P2P :9000 (TCP) + :9001 (WS)\nlibp2p + mDNS + DHT"
Loading

Leyenda

Capa Paquete Propósito
🖥️ Interfaz pkg/api/, pkg/ws/ REST API + WebSocket — punto de entrada para clientes
🗂️ Dominio pkg/db/, pkg/auth/ Modelo de datos, autenticación, lógica de negocio
🌐 Red pkg/p2p/, pkg/db/sync.go Conexión P2P (libp2p), descubrimiento mDNS/DHT, sincronización
🔒 Seguridad pkg/config/, pkg/backup/, pkg/encryption/ Cifrado, backups, configuración segura
🛠️ Utilidades pkg/util/, pkg/ratelimit/, pkg/audit/, pkg/anonymization/, pkg/binary/ Sanitización, rate limiting, auditoría, anonimización, archivos binarios
🌐 Frontend index.html, tienda.html, dbp2p.js, binary_utils.js Clientes web que consumen API REST + WebSocket

Flujo de Datos

flowchart LR
    subgraph Cliente
        HTML[index.html / tienda.html]
        JS[dbp2p.js]
    end

    subgraph Backend
        API["API REST :8090<br/>pkg/api/"]
        WS["WebSocket :8100<br/>pkg/ws/"]
        DB[(Database<br/>pkg/db/)]
        P2P["P2P :9000<br/>pkg/p2p/"]
    end

    subgraph Red
        PEERS[Otros Nodos]
    end

    HTML -->|fetch /api/*| API
    JS -->|WebSocket /ws| WS
    API --> DB
    WS --> DB
    DB -->|pubsub sync| P2P
    P2P <-->|libp2p| PEERS

    style HTML fill:#e1f5fe
    style JS fill:#e1f5fe
    style API fill:#dcedc8
    style WS fill:#dcedc8
    style DB fill:#fff9c4
    style P2P fill:#f8bbd0
    style PEERS fill:#f8bbd0
Loading

About

Base de datos distribuida

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors