Tolerancia a Fallos y Finalidad
Garantías BFT
El consenso de Savitri utiliza un protocolo de votación BFT (Tolerante a Fallos Bizantinos) con un quórum de 2f+1 (umbral del 67%).
Tolerancia a Fallos
| Total de Nodos (n) | Máx. Bizantinos (f) | Quórum Requerido |
|---|---|---|
| 3 | 0 | 2 |
| 5 | 1 | 4 |
| 7 | 2 | 5 |
| 10 | 3 | 7 |
| 15 | 4 | 11 |
Fórmula: f = floor((n-1) / 3), quórum = 2f + 1
Seguridad
Un bloque solo se finaliza cuando se produce un Certificado de Aceptación de Bloque (BAC) con firmas de 2f+1 validadores. Esto garantiza:
- Ningún bloque conflictivo puede finalizarse en la misma altura
- Sin retrocesos una vez emitido un BAC (finalidad determinista, no probabilista)
- Los nodos bizantinos no pueden falsificar certificados sin participación en el quórum
Disponibilidad
La red puede producir bloques siempre que n - f nodos honestos estén en línea:
- Rotación de propositor: Tras 50 bloques, el propositor cede para evitar un punto único de fallo
- Watchdog de elección: Vuelve a disparar la elección si no hay progreso de bloques en 60 segundos
- Relajación progresiva del quórum: Tras 3+ fallos consecutivos de elección, el mínimo de candidatos baja a 2
Estructura DAG
Las cabeceras de bloque admiten una estructura DAG de múltiples padres para la producción concurrente de bloques:
pub struct BlockHeader {
pub parent_hash: Vec<u8>, // padre principal (compatible hacia atrás)
pub parent_hashes: Vec<Vec<u8>>, // padres adicionales para DAG
// ...
}
Detección de Conflictos
El ConflictDetector identifica:
- Conflictos de doble gasto: El mismo UTXO referenciado en múltiples ramas
- Conflictos de estado: Transiciones de estado conflictivas
- Detección de bifurcaciones: Múltiples bloques en la misma altura de diferentes propositores
Resolución de Conflictos
Cuando se detectan conflictos:
- Elegir la rama con mayor puntuación PoU acumulada
- Revertir las transacciones conflictivas
- Re-aplicar las transacciones no conflictivas de la rama perdedora
Consenso Consciente de Grupos
Formación de Grupos
Los Masternodes organizan los lightnodes en grupos:
- Ordenar los lightnodes por puntuación PoU
- Asignar a grupos de
group_size(3 en desarrollo, 7 en producción) - Publicar las asignaciones de grupo vía gossipsub
- IDs de grupo deterministas basados en época (no en tiempo de reloj)
Elección Intragrupal
Dentro de cada grupo:
- Los miembros comparten las puntuaciones PoU
- La puntuación PoU más alta se convierte en propositor (desempate por peer_id)
- Se requiere un mínimo de
(total+1)/2candidatos - Tras 3+ fallos: relajar al mínimo de 2 candidatos
Aceptación de Bloque
- El propositor del grupo produce un bloque
- Los miembros del grupo verifican y firman
- BAC producido con 2f+1 firmas
- Los Masternodes verifican el BAC y finalizan
Mecanismos de Recuperación
Recuperación de Elección
| Mecanismo | Disparador | Acción |
|---|---|---|
| Temporizador watchdog | Sin bloque en 60s | Re-disparar PoU + elección |
| Relajación progresiva | 3+ fallos | Bajar quórum a 2 |
| Rotación de propositor | 50 bloques | Ceder y re-elegir |
| Re-elección inmediata | Re-inicio de grupo | Lanzar tarea PoU + elección |
Recuperación de Pares
| Mecanismo | Disparador | Acción |
|---|---|---|
| Keepalive de Gossipsub | Intervalo de 60s | Publicar puntuación PoU |
| Watchdog de recuperación de malla | Sin malla en 60s | Re-marcar pares del grupo |
| Desconexión de SlowPeer | Cola saturada | Desconectar y reconectar |
| Restablecimiento de nonce | Local > almacenamiento + 200 | Restablecer al nonce de almacenamiento |
Recuperación de Grupo
Cuando un grupo se re-inicializa:
- Las puntuaciones PoU se conservan para los miembros continuos
- Los nuevos miembros comienzan con puntuaciones por defecto
- La bandera
intra_group_startedse restablece - Se lanza inmediatamente PoU + elección (sin esperar los temporizadores periódicos)
Penalizaciones (Producción)
| Infracción | Penalización | Período de Espera |
|---|---|---|
| Doble voto | 50% del stake | N/A |
| Tiempo de inactividad | 10% del stake | Gradual |
| Propuesta inválida | 25% del stake | N/A |
Las penalizaciones están desactivadas en devnet y activadas en mainnet (config/production.toml).
Configuración del Consenso
| Parámetro | Desarrollo | Producción |
|---|---|---|
| Tiempo de espera | 15s | 10s |
| Máx. rondas | 5 | 10 |
| Umbral de quórum | 0.67 | 0.67 |
| Optimizaciones BFT | Desactivadas | Activadas |
| Penalizaciones | Desactivadas | Activadas |
| Tiempo de bloque | 2s | 5s |
| Tamaño de grupo | 3 | 7 |