Mi homelab forjó 57 endorser blocks de Leios — lo que aprendí como BP de testnet
Follow-up hands-on: evidencia de forja local, honestidad del cap de EB, sobrevivir un respin y por qué la latencia del día de release no es un bug.

En junio monté un nodo de Ouroboros Leios en Musashi Dōjō, medí el throughput de endorser blocks bajo la carga de IOG y registré un stake pool. La promesa al final era simple: cuando el snapshot de stake se activara, el homelab empezaría a forjar endorser blocks.
Lo hizo.
Este es el follow-up: evidencia de forja local, una lectura más limpia del cap de 2.184 tx por EB, un respin que casi se convierte en un bug report falso, y un re-test de latencia cuando la red ya estaba calmada. Mismo contenedor de homelab, misma identidad de pool, genesis nuevo, release nuevo (`prototype-2026w28`, `cardano-node 11.1.0.164`).
Qué significa "forjar" aquí — y qué no
El 2026-07-12, epoch 11, nuestro block producer registró:

| Señal | Conteo (día parcial → ~16:09 UTC) |
|---|---|
| `NodeIsLeader` | 137 |
| `LeiosBlockForged` | 57 |
| EBs al cap del protocolo (2.184 tx) | 27 |
| Suma de `numTxs` en nuestros EBs | 99.203 |


Esos eventos salen de `Consensus.LeiosKernel.BlockForged` en el kernel local del block producer, no de un explorer de terceros. Primer EB del día: `2026-07-12T01:12:21Z`, slot `954741`, `numTxs` 1181, hash `77efc0d64c7a39736b83d1abe94e66b5a23cd13eec97952bea26a755c393c6f0`.
Sí significa: nuestro pool (`60ef1953…` / `pool1vrh3j56…`) fue elegido líder y el nodo produjo endorser blocks en local.
No significa: que produzcamos el X% de los EBs de la red, que todos los peers descargaran nuestros bloques, ni que operemos un relay público inbound. No operamos un relay de entrada pública para este artículo: la conectividad relevante es saliente y las afirmaciones de forja se apoyan en logs locales, no en ser un punto de entrada de la red.
El número 2.184, dicho con cuidado
En junio el endorser block más grande que vimos cargaba 2.184 transacciones — y una ventana de ~10 s de tiempo de cadena llegó a ~218 TPS. Sigue siendo buena intuición, pero la frase limpia es:


2.184 es el cap del bitmap de inclusión de un EB (≈ 2.184 × 36 B de refs ≈ 78.627 bytes de cuerpo). Un EB lleno en 10 s ≈ 218 tx/s. Eso es cap-bound, no un estudio formal de capacidad multi-hora, y la carga que llenó esos bloques la generan los load generators de IOG, no nuestro submitter.
El 12 de julio, de los 57 EBs que forjamos:
| Rango `numTxs` | Cantidad |
|---|---|
| 1–500 | 4 |
| 501–1500 | 10 |
| 1501–2000 | 13 |
| 2001–2183 | 3 |
| 2184 (cap) | 27 |
Mediana ≈ 2.149, media ≈ 1.740. Casi la mitad de nuestros EBs tocan el mismo techo que reportamos en junio — ahora desde el lado productor del log.
Sobrevivir un respin silencioso (y casi reportar el bug equivocado)
Hacia el 2026-07-01 la testnet renació con genesis nuevo. Nuestro nodo llevaba días atascado en un slot bajo con `NoCounterForKeyHashOCERT`: no era "el binario roto" en abstracto, sino headers de un ledger que no teníamos. La aritmética de slots frente al `systemStart` viejo bastó para demostrar el respin antes de ver changelog.
Lecciones que merecen publicarse:
- Las testnets prototipo hacen respin sin ceremonia. Las claves sobreviven; el registro on-chain y el faucet, no. El pool id es determinista de las cold keys.
- Binarios y configs viajan juntos. Un half-update parece "aplicado" y envenena el siguiente diagnóstico.
- Nunca hardcodear el KES period. Calcular `slot / slotsPerKESPeriod`; counter del opcert a 0 en ledger fresco.
- `build-raw` + draft `+0` subestima el fee por diseño. El casi-"bug de la cli" eran 8 bytes CBOR del change (352 lovelace = 44 × 8). Verificar aritmética antes de abrir issue.
- El faucet `delegate` quiere bech32 (`pool1…`), no hex.
- No publicar rendimiento el día del release.
Tras detectar el respin: tip + re-registro en <40 min con un solo paso humano en el faucet.
Latencia: el día que casi gritamos "regresión"
El 2026-07-10 — el mismo día que salió `w28` — las txs externas se veían mal: 4–30 min en txs sueltas, un burst de 200 en 7–8 min. Frente a w25 (~34 s), olía a regresión.
Era una ventana de despliegue. Re-medido el 2026-07-12 con la red más quieta:
| Métrica | 2026-07-10 (día de release) | 2026-07-12 (estable) |
|---|---|---|
| Tx de control | 4–30 min | ~87 s (N=1) |
| Burst 200 (5×40, submitter pre-firmado) | 7–8 min | ~45 s a 5/5 tips; 0/200 errores |
| vs burst w25 (~34 s) | susto | usable, un poco más lento |

Regla: un claim de rendimiento en red compartida necesita (a) mirar si hubo release ese día, y (b) reproducirse en ≥1 día tranquilo antes de titular. N pequeño vale si se etiqueta; claims grandes, no.
Método, a la vista
- Conteos de forja: parsear `node.log` por `NodeIsLeader` y `LeiosBlockForged` del `2026-07-12`.
- Throughput (baseline de junio): `leios_peak.py` — bitmaps por `ebHash`, popcount, slotLength 1 s, ventanas deslizantes. Scripts: leios-homelab-loadtest.
- Submit (julio): txs encadenadas pre-firmadas (`submitter.py`), no cientos de `cardano-cli` en paralelo (cuello de junio = cliente, no Leios).
- Hardware: contenedor en homelab (clase 4 vCPU / 4 GB).
- No corrido para esta pieza: test de techo `20×400` @ 150 tx/s (~1,6k ADA de test en fees). Artículo opcional después; no hace falta para forja + método.
Lo que me llevo
Leios en Musashi Dōjō ya no es solo "vi 218 TPS en los logs". Es forjé 57 endorser blocks en un día, toqué el cap de 2.184 desde el productor, y aprendí que la honestidad operativa (respin, KES, fees, no medir el día del release) es media historia de una testnet de investigación.
El futuro de throughput de Cardano sigue siendo un prototipo. Los prototipos renacen. Los números se mueven. El trabajo de un write-up de homelab no es congelar un TPS de marketing: es mostrar evidencia primaria, no-afirmaciones claras y un método con el que otro operador pueda discrepar con producto.
Datos: BP propio en Musashi Dōjō (magic 164), epoch 11, 2026-07-12 (conteos a ~16:09 UTC). Artículo previo: [nodo + medición de junio](https://danonight.com/es/noticias/leios-node-homelab). Scripts: https://github.com/amvs0122/leios-homelab-loadtest.


