Saltar al contenido
Finance & Banking
Evolution Program
Inicio / modules / 18-blockchain-y-dlt-para-instituciones-financieras / solutions

Solución de referencia — Laboratorio 4: consenso con nodos defectuosos

Material docente.

Contar nodos no es contar independencias

Es el hallazgo del laboratorio y de la clase 5.

n = 5, f = 1
  el protocolo tolera UN nodo que miente

  PERO si 3 de los 5 ejecutan la misma implementación
  y esa implementación tiene un defecto que produce
  el mismo resultado incorrecto en los tres:

  → 3 votos coincidentes y erróneos
  → 3 ≥ 2f + 1 = 3
  → EL SISTEMA ACUERDA UN VALOR ERRÓNEO

El consenso bizantino tolera participantes que mienten de forma independiente. Tres nodos que se equivocan igual no son tres fallos: son uno.

Umbral medido

n = 4 (f = 1)
  0 mentirosos  → acuerdo en 1 ronda
  1 mentiroso   → acuerdo en 1 ronda
  2 mentirosos  → SIN acuerdo, el sistema se detiene

n = 7 (f = 2)
  2 mentirosos  → acuerdo
  3 mentirosos  → SIN acuerdo

MEDIDO, NO SUPUESTO: el laboratorio lo ejecuta.

Detenerse en vez de divergir

def test_sin_quorum_no_hay_dos_estados(red):
    red.configurar(nodos=4, mentirosos=2)
    resultado = red.ejecutar_ronda()

    assert resultado.decidido is False
    estados = {n.estado_actual() for n in red.nodos_honestos()}
    assert len(estados) == 1     # todos en el MISMO estado anterior

La segunda comprobación es la importante: sin quórum, los honestos no avanzan y no divergen. En finanzas eso es lo correcto (clase 1): divergir es crear dinero.

El fallo común

def test_el_fallo_comun_produce_acuerdo_erroneo(red):
    # Tres nodos con la MISMA implementacion defectuosa:
    # no mienten, se equivocan igual.
    red.configurar(nodos=5, con_defecto_comun=3)
    resultado = red.ejecutar_ronda()

    assert resultado.decidido is True
    assert resultado.valor == VALOR_INCORRECTO

Esta prueba debe pasar. Documenta la limitación que ningún umbral corrige y que el expediente de la clase 14 tiene que declarar como riesgo residual.

Mensajes por ronda

n = 4   → 16 mensajes
n = 7   → 49
n = 10  → 100

crecimiento cuadrático confirmado

CON n ENTRE 5 Y 20, ES IRRELEVANTE
  el «no escala» que se le reprocha al consenso
  bizantino es un criterio de red abierta,
  no de consorcio

Detección de desviación de orden

def desviacion(bloque, mempool_firmada) -> list[str]:
    """Devuelve las operaciones incluidas fuera de su turno."""
    esperado = sorted(mempool_firmada, key=lambda t: (t.recibido_en, t.id))
    incluidas = bloque.transacciones
    fuera = []
    for posicion, tx in enumerate(incluidas):
        if posicion < len(esperado) and tx.id != esperado[posicion].id:
            fuera.append(tx.id)
    return fuera

No impide la desviación: la hace detectable y atribuible, que es lo alcanzable (clase 5).

Errores que se penalizan

Error Por qué
Suponer el umbral El laboratorio existe para medirlo
No probar el fallo común Es el hallazgo de la clase
Comprobar solo que no hay acuerdo Falta comprobar que no divergen
Concluir que «no escala» Con pocos participantes escala
Rotación sin detección Resuelve el turno, no la elección

Límites