Ethereum: de historia a labs

Artículo 45 de 48

94%

completado al llegar aquí

Sistemas distribuidosNota de investigación12 min de lectura

Clientes y nodos: diversidad antes que monocultivo

Qué corre dentro de un nodo Ethereum: cliente de ejecución, cliente de consenso y Engine API, y por qué ningún cliente debería superar un tercio de la red.

Ruta Ethereum: 0/48

Tu equipo decide correr un nodo propio para no depender de un proveedor de RPC. Alguien instala un cliente de ejecución, abre el puerto JSON-RPC y espera. El nodo descarga datos, pero nunca alcanza la punta de la cadena. No hay error evidente. ¿Qué falta?

Falta la mitad del nodo. Desde The Merge, un nodo de Ethereum son dos programas que cooperan: un cliente de ejecución y un cliente de consenso. Este capítulo explica qué hace cada uno, cómo se hablan, qué datos puede servir tu nodo según cómo lo configures y por qué la red entera depende de que no todos elijan el mismo software.

Flujo visual

Cómo avanza la cabeza dentro de un nodo

El cliente de consenso decide qué bloque es la cabeza; el cliente de ejecución valida y ejecuta su contenido.
  1. Llega un bloque por la red de consensoEl cliente de consenso recibe el bloque de la Beacon Chain con su carga de ejecución.
  2. engine_newPayloadEntrega la carga al cliente de ejecución, que la ejecuta en la EVM y responde si es válida.
  3. Fork choiceEl cliente de consenso aplica sus reglas y elige head, safe y finalized.
  4. engine_forkchoiceUpdatedComunica esos tres hashes al cliente de ejecución.
  5. JSON-RPC respondeTu aplicación lee latest, safe y finalized desde el cliente de ejecución.

Brújula de lectura

Actor, evidencia y estado

Antes de avanzar, ubica quién actúa, qué prueba queda y qué parte del sistema cambia.

Actor

Par de clientes

Un cliente de ejecución y uno de consenso, de equipos y lenguajes que tú eliges.

Evidencia

Especificación común

Todos los clientes implementan las mismas specs; un bug fuera de la spec es local a un cliente.

Estado

Cabeza y estado de la EVM

El consenso fija qué cadena seguir; la ejecución guarda cuentas, contratos y recibos.

Preguntas guía

Lee con estas preguntas a mano; todas aparecen cuando un equipo opera su propio nodo:

  • ¿Qué cliente decide cuál es el bloque finalized que ves por JSON-RPC?
  • ¿Qué pasa si el puerto de la Engine API queda expuesto a internet?
  • ¿Puede tu nodo responder el saldo de una cuenta en un bloque de hace dos años?
  • Si un cliente con la mitad de la red tiene un bug, ¿qué le pasa a la finalidad?
  • ¿Qué comprobaciones de salud distinguen "proceso vivo" de "nodo útil"?

Conexiones dentro de la serie

Prerequisitos internos recomendados:

Traza de ejecución dentro de un nodo: dos clientes, tres interfaces

Un cliente es una implementación de Ethereum que verifica datos contra las reglas del protocolo. El cliente de ejecución escucha transacciones, las ejecuta en la EVM y guarda el estado y la base de datos de la cadena. El cliente de consenso implementa la prueba de participación y decide qué cadena seguir a partir de los datos que valida el cliente de ejecución. Un tercer programa opcional, el cliente validador, se conecta al de consenso para proponer bloques y votar.

Cada cliente expone su propia interfaz. Tu aplicación habla con el cliente de ejecución por JSON-RPC, la API del capítulo de RPC. Los operadores consultan el cliente de consenso por la Beacon API, una API REST para observar la capa de consenso.

La tercera interfaz une a los dos clientes: la Engine API. El cliente de ejecución la expone en un puerto separado del JSON-RPC, por defecto el 8551, y exige autenticación con un token JWT firmado con HMAC-SHA256 a partir de un secreto compartido de 256 bits. La especificación explica de qué protege: de un puerto expuesto a internet y de páginas web maliciosas que intenten hablar con él desde el navegador.

Por la Engine API circulan dos llamadas centrales. engine_newPayload entrega al cliente de ejecución la carga de un bloque para que la valide. engine_forkchoiceUpdated le comunica tres hashes: headBlockHash, safeBlockHash y finalizedBlockHash. De ahí salen las etiquetas latest, safe y finalized que tu indexador consulta por JSON-RPC: el cliente de ejecución no las calcula, las recibe.

Figura 1

Un nodo Ethereum: dos clientes unidos por la Engine API

Fuentes:

[3][4]
Un nodo Ethereum: dos clientes unidos por la Engine API
Cómo leer esta figura

Dos cajas grandes dentro de un nodo. A la izquierda, el cliente de consenso, conectado a la red de consenso entre pares y opcionalmente a un cliente validador, con la Beacon API hacia el operador. A la derecha, el cliente de ejecución, conectado a la red de ejecución entre pares, con la EVM y el estado, y con JSON-RPC hacia la aplicación. Entre ambos, la Engine API en el puerto 8551 con JWT: una flecha engine_newPayload va del consenso a la ejecución y vuelve con VALID o INVALID; otra flecha engine_forkchoiceUpdated lleva tres hashes: head, safe y finalized.

Visual original de TrautsLab. El cliente de consenso valida bloques con el cliente de ejecución mediante engine_newPayload y le comunica head, safe y finalized con engine_forkchoiceUpdated. Tu aplicación solo ve JSON-RPC; el operador vigila la Beacon API.

Qué datos puede servir tu nodo

No todos los nodos guardan lo mismo. Un nodo completo (full node) valida bloque a bloque, pero solo conserva el estado reciente, típicamente los últimos 128 bloques, y poda el resto para ahorrar disco. Un nodo de archivo (archive node) guarda además todos los estados históricos; es lo que necesitas para preguntar el saldo de una cuenta en el bloque 4 000 000. Ocupa del orden de terabytes.

Para un equipo de producto, la consecuencia es concreta. Una llamada como eth_getBalance con un número de bloque antiguo funciona en un nodo de archivo y falla en uno completo. Lo mismo ocurre con trazas de transacciones antiguas. Antes de elegir el tipo de nodo, lista las consultas históricas que tu negocio necesita de verdad.

Además del estado, está la historia: bloques y recibos. Desde la expiración parcial de historia de 2025, un nodo puede no tener los bloques anteriores a The Merge. Si tu conciliación depende de logs antiguos, ese dato tiene que venir de otra fuente; el capítulo de indexadores cita el anuncio y sus consecuencias para un backfill.

Estado de votos: por qué un tercio y dos tercios gobiernan la diversidad

Todos los clientes siguen una especificación común. Diversidad de clientes significa que los nodos de la red se reparten entre implementaciones distintas, escritas por equipos distintos. La razón es estadística: un bug en un cliente minoritario afecta a pocos nodos; el mismo bug en un cliente mayoritario afecta a la red.

Hay un precedente. En el ataque de denegación de servicio de Shanghái, en 2016, los atacantes hicieron que Geth, el cliente dominante, ejecutara una operación lenta de disco decenas de miles de veces por bloque. La red siguió operando porque había clientes alternativos sin esa vulnerabilidad mientras se corregía Geth.

Con prueba de participación aparecen dos umbrales. La finalidad requiere votos de dos tercios del stake. Si un cliente de consenso que corre más del 33 % de la red tiene un bug que le impide votar bien, la red no finaliza. Si un cliente con dos tercios tiene un bug crítico, la cadena puede finalizar un bloque inválido, y sus validadores quedan atrapados: volver a la cadena correcta los expone a slashing o a una salida lenta y costosa.

Por eso la recomendación es que ningún cliente supere el 33 % de los nodos, y la misma lógica aplica a la capa de ejecución: un bug en un cliente de ejecución dominante al construir o validar cargas puede llevar a que la red finalice transacciones erróneas. El snapshot de octubre de 2025 que publica ethereum.org mostraba al cliente más usado de cada capa por encima de ese 33 %; la propia página advierte que los datos pueden estar desactualizados y remite a paneles en vivo.

Riesgo operativo: elegir y vigilar tu par de clientes

Para un equipo que opera depósitos y retiros, la diversidad no es solo un bien público. Si tu único nodo corre el cliente que falla, tu servicio ve una cadena que el resto de la red no reconoce, o deja de ver finalidad. Una mitigación razonable es tener al menos dos fuentes con pares de clientes distintos y comparar su bloque finalized antes de liberar fondos.

"El proceso está vivo" no es una comprobación útil. Lo que importa es si el nodo está sincronizado, si su cliente de ejecución responde y si la finalidad avanza. Las APIs ya traen esas señales:

  • eth_syncing en JSON-RPC devuelve false o un objeto con el progreso de sincronización.
  • /eth/v1/node/health en la Beacon API responde 200 si el nodo está listo, 206 si está sincronizando o si su cliente de ejecución está en modo optimista o fuera de línea, y 503 si tiene problemas. Está pensado para balanceadores de carga.
  • /eth/v1/node/syncing devuelve sync_distance, is_optimistic y el_offline, y /eth/v1/beacon/states/{state_id}/finality_checkpoints muestra los checkpoints justificados y finalizados.

Este script es ilustrativo: los puertos dependen de cómo configures cada cliente, por eso van en variables.

Bash
#!/usr/bin/env bash
# Ilustrativo: comprobaciones de salud de un par de clientes.
# EL_RPC=http://127.0.0.1:<puerto JSON-RPC>  BEACON=http://127.0.0.1:<puerto Beacon API>
set -euo pipefail
 
rpc() {
  curl -s -X POST -H 'content-type: application/json' \
    --data "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"$1\",\"params\":$2}" "$EL_RPC"
}
 
rpc eth_syncing '[]' | jq '.result'
rpc eth_getBlockByNumber '["finalized", false]' | jq -r '.result.number'
 
curl -s -o /dev/null -w 'beacon health: %{http_code}\n' "$BEACON/eth/v1/node/health"
curl -s "$BEACON/eth/v1/node/syncing" | jq '.data | {sync_distance, is_optimistic, el_offline}'
curl -s "$BEACON/eth/v1/beacon/states/head/finality_checkpoints" | jq '.data.finalized'
Decisión de infraestructura

¿De dónde lee tu servicio la cadena?

Precaución

Solo proveedor RPC

Menos operación; el proveedor elige clientes y tipo de nodo.

Ideal para
Lecturas de interfaz y prototipos.
Ojo con
No ves qué cliente responde ni si su finalized coincide con la red.

Nodo propio, un par

Controlas configuración, puertos y retención de datos.

Ideal para
Equipos que necesitan independencia de terceros.
Ojo con
Si tu par de clientes falla, no tienes con qué comparar.
Recomendado

Dos fuentes con clientes distintos

Nodo propio más proveedor, o dos nodos con pares diferentes.

Ideal para
Liberar depósitos y aprobar retiros.
Ojo con
Define qué hacer cuando discrepan: detener y alertar, no elegir al azar.
La pregunta no es nodo propio contra proveedor, sino cuántas fuentes independientes confirman lo que vas a pagar.

Lo esencial de un nodo

Quédate con tres ideas. Un nodo son dos clientes, y el de consenso decide las etiquetas que tu aplicación consulta. La Engine API nunca se expone fuera del host. Y la diversidad de clientes es un control de riesgo: el tuyo, al comparar fuentes, y el de la red, al no darle a ningún software más de un tercio.

Referencias

Bibliografía académica

Formato IEEENumerado para ingeniería, sistemas y protocolos.
  1. [1]

    ethereum.org, "Nodes and clients."

    official docsID: ETH-NODES-CLIENTSAbrir fuente (abre en otra pestaña)

    Clientes de ejecución, consenso y validador; tipos de nodo.

  2. [2]

    ethereum.org, "Client diversity."

    official docsID: ETH-CLIENT-DIVERSITYAbrir fuente (abre en otra pestaña)

    Umbrales de 33 % y dos tercios, ataque de 2016 y snapshot de octubre de 2025.

  3. [3]

    Ethereum Execution APIs, "Engine API: Authentication."

    Puerto 8551, JWT HS256, secreto jwt-secret y amenazas cubiertas.

  4. [4]

    Ethereum Execution APIs, "Engine API: Paris."

    engine_newPayloadV1 y engine_forkchoiceUpdatedV1 con head, safe y finalized.

  5. [5]

    Ethereum Beacon APIs specification.

    Endpoints /eth/v1/node/health, /eth/v1/node/syncing y finality_checkpoints.

  6. [6]

    ethereum.org, "Gasper."

    official docsID: ETH-GASPER-DOCSAbrir fuente (abre en otra pestaña)

    Justificación y finalización con dos tercios del stake.

  7. [7]

    Ethereum Execution APIs specification.

    specID: ETH-EXECUTION-APISAbrir fuente (abre en otra pestaña)

    eth_syncing, eth_blockNumber y etiquetas de bloque.

Fuentes primarias, papers seminales y especificaciones técnicas citadas en esta investigación.

Rutas vecinas

Si este tema te abrió hambre, sigue por aquí.

Series y labs que comparten área o dependen de esta ruta. Pocas opciones, para no convertir la curiosidad en menú infinito.

Sigue leyendo

Ideas conectadas con este artículo

Una ruta corta para continuar sin abrir veinte pestañas y perder el hilo.

Los comentarios se cargan al final de la lectura para no meter peso antes de tiempo.