Un nodo OP Stack no es un único binario, sino un par de procesos: un cliente de consenso/derivación de rollup (op-node) y un cliente de ejecución de Ethereum (op-geth u op-reth) que op-node controla a través de la Engine API. op-node lee la L1 para obtener datos de lotes del secuenciador, deriva la cadena L2 canónica y envía payloads al cliente de ejecución mediante newPayload y forkchoiceUpdated. El cliente de ejecución expone la superficie JSON-RPC estándar eth_*, por lo que las dapps ven el mismo RPC independientemente de si se usa op-geth u op-reth. Un único binario op-node sirve a cualquier cadena de la Superchain —Optimism, Base, Unichain— cargando una configuración de rollup específica de la cadena en lugar de requerir un binario diferente. Este artículo explica la arquitectura, la configuración, la verificación y la resolución de problemas del par de clientes de nodo OP Stack.
El modelo de nodo OP Stack de dos procesos
A diferencia de un cliente Ethereum monolítico como Geth o Nethermind, un nodo OP Stack se compone de dos procesos distintos que se comunican a través de la Engine API. El primero es un cliente de consenso y derivación de rollup, normalmente op-node, que lee la cadena L1 (Ethereum) para obtener datos de lotes del secuenciador y entradas de derivación. El segundo es un cliente de ejecución de Ethereum —ya sea op-geth (un fork de Geth) u op-reth (un cliente basado en Reth)— que mantiene el estado de la L2, ejecuta transacciones y expone la interfaz JSON-RPC estándar eth_*. Esta separación está documentada en la arquitectura de nodo de Optimism y es fundamental para cómo operan las cadenas OP Stack.
Debido a que los dos procesos son separados, debes ejecutar ambos y conectarlos correctamente. op-node no ejecuta transacciones ni mantiene estado; solo deriva la cadena L2 canónica a partir de los datos de la L1 e indica al cliente de ejecución qué bloques importar. El cliente de ejecución no lee la L1 directamente; depende enteramente de op-node para nuevos payloads y actualizaciones de forkchoice. Esta división del trabajo significa que un endpoint RPC de L1 en mal estado bloqueará op-node, lo que a su vez bloqueará al cliente de ejecución, incluso si el cliente de ejecución en sí está perfectamente sano.
La conexión de la Engine API entre op-node y el cliente de ejecución se autentica con un secreto JWT. Esta es la misma Engine API que utiliza la capa de consenso de Ethereum, pero aquí op-node actúa como el cliente de consenso. El cliente de ejecución debe iniciarse con la Engine API habilitada y el mismo secreto JWT que usa op-node. Sin esta autenticación, op-node no puede enviar payloads y el nodo no se sincronizará.
- op-node: cliente de consenso/derivación de rollup; lee la L1, deriva la L2, controla el cliente de ejecución a través de la Engine API.
- op-geth u op-reth: cliente de ejecución; mantiene el estado de la L2, expone JSON-RPC eth_*.
- Engine API: canal autenticado (JWT) para llamadas newPayload y forkchoiceUpdated.
- Ambos procesos deben ejecutarse; ninguno es opcional para un nodo OP Stack completo.
Rol de op-node: derivación e interacción con la Engine API
op-node es el cerebro del nodo OP Stack. Lee continuamente la cadena L1 para dos tipos de datos: transacciones de lotes del secuenciador (que contienen datos de transacciones de la L2) y entradas de derivación como atributos de bloques de la L1. Usando estos, deriva la cadena L2 canónica de acuerdo con las reglas del protocolo de rollup. El proceso de derivación está especificado en las especificaciones de Optimism e implica una máquina de estados que rastrea el origen L1 y la cabeza segura de la L2.
Una vez que op-node ha derivado un nuevo bloque L2, envía el payload del bloque al cliente de ejecución a través del método newPayload de la Engine API. Luego llama a forkchoiceUpdated para establecer la nueva cabeza y, cuando corresponde, los hashes de bloque seguro y finalizado. Este es el mismo flujo de la Engine API que utiliza la capa de consenso de Ethereum, pero con atributos de payload específicos de OP Stack. El cliente de ejecución valida e importa el bloque, actualizando su estado y haciendo que el nuevo bloque esté disponible a través de eth_getBlockByNumber.
op-node también expone su propio espacio de nombres JSON-RPC, optimism_*, que incluye métodos como optimism_syncStatus y optimism_outputAtBlock. Estos son útiles para monitorear el progreso de la derivación y verificar que la cabeza de la L2 sigue a la cabeza de derivación de la L1. Para profundizar en las llamadas de la Engine API, consulta Engine API newPayload y forkchoice.
- Lee la L1 para lotes y entradas de derivación.
- Deriva la cadena L2 canónica según las reglas del rollup.
- Envía payloads a través de la Engine API newPayload y forkchoiceUpdated.
- Expone RPC optimism_* para estado de sincronización y raíces de salida.
Clientes de ejecución: op-geth y op-reth
El cliente de ejecución es responsable de mantener el estado de la L2, ejecutar transacciones y servir la API JSON-RPC estándar de Ethereum. Existen dos implementaciones principales: op-geth, que es un fork de Go Ethereum, y op-reth, que está construido sobre la arquitectura del cliente Reth. Ambos implementan la misma lógica de ejecución y transición de estado, y ambos exponen la misma superficie JSON-RPC eth_*. Esto significa que, desde la perspectiva de una dapp, la elección del cliente de ejecución no cambia la interfaz RPC: eth_chainId, eth_blockNumber, eth_getBlockByNumber y todos los demás métodos estándar se comportan de manera idéntica.
La elección entre op-geth y op-reth es una compensación operativa. op-geth se beneficia de la madurez y familiaridad de la base de código de Geth, con amplias herramientas y documentación. op-reth, al ser más nuevo, puede ofrecer ventajas de rendimiento en ciertas cargas de trabajo debido a su implementación en Rust y su arquitectura modular. Sin embargo, ambos están listos para producción y son utilizados por operadores de nodos. La decisión debe basarse en la experiencia de tu equipo, tu stack de monitoreo y tus requisitos de rendimiento, no en la compatibilidad RPC.
Ambos clientes admiten la Engine API y pueden ser controlados por op-node. También admiten los mismos formatos de base de datos y mecanismos de instantáneas, aunque op-reth puede tener requisitos de almacenamiento diferentes. Al ejecutar un nodo, debes asegurarte de que la versión del cliente de ejecución sea compatible con tu versión de op-node, ya que la Engine API y el protocolo OP Stack evolucionan.
- op-geth: fork de Geth, maduro, herramientas familiares.
- op-reth: basado en Reth, Rust, posibles beneficios de rendimiento.
- Ambos exponen una superficie JSON-RPC eth_* idéntica.
- La elección es operativa, no funcional para las dapps.
Un único binario op-node para cualquier cadena de la Superchain
Una característica clave del diseño de OP Stack es que un único binario op-node puede servir a cualquier cadena de la Superchain —Optimism, Base, Unichain y otras— cargando una configuración específica de la cadena. Esta configuración, a menudo llamada configuración de rollup o configuración de cadena, incluye parámetros como el ID de cadena de la L2, las direcciones de los contratos de configuración del sistema, la cadena L1 de la que deriva y la URL del feed del secuenciador. No hay un binario separado para cada cadena; la misma base de código se ejecuta en todas partes.
Este es el mecanismo detrás de la narrativa de 'una Superchain'. Cuando inicias op-node, le proporcionas la configuración de rollup para tu cadena objetivo. Por ejemplo, para ejecutar un nodo de Base, usas la configuración de rollup de Base; para ejecutar un nodo de Optimism, usas la configuración de rollup de Optimism. Luego, op-node lee los contratos L1 apropiados y deriva la cadena L2 correcta. Esta uniformidad simplifica las herramientas y permite a los proveedores de infraestructura admitir múltiples cadenas con los mismos procedimientos operativos.
La configuración de rollup normalmente se distribuye como un archivo JSON o se obtiene de un registro de cadenas. Incluye el ID de cadena de la L1, el ID de cadena de la L2, la dirección de la bandeja de entrada de lotes, la dirección del secuenciador y otros parámetros. Para obtener una lista de las cadenas OP Stack y sus configuraciones, consulta la documentación de Optimism.
- El mismo binario op-node para todas las cadenas de la Superchain.
- Parámetros específicos de la cadena cargados mediante la configuración de rollup.
- La configuración incluye ID de cadena L2, ID de cadena L1, direcciones de contratos, feed del secuenciador.
- Permite herramientas y operaciones uniformes en todas las cadenas.
Poner en marcha un nodo OP Stack: compilación y configuración
Para ejecutar un nodo OP Stack, necesitas compilar o descargar los binarios de op-node y del cliente de ejecución, y luego configurarlos para que funcionen juntos. Comienza obteniendo las últimas versiones de los repositorios oficiales: op-node del monorepositorio de Optimism, y op-geth u op-reth de sus respectivos repositorios. También necesitarás un endpoint RPC de Ethereum L1 en buen estado, ya que op-node lee la L1 para obtener lotes. Este endpoint L1 es una dependencia crítica; si no está disponible, op-node no puede derivar nuevos bloques L2.
A continuación, genera un secreto JWT para la autenticación de la Engine API. Tanto op-node como el cliente de ejecución deben usar el mismo secreto. Luego, inicia el cliente de ejecución con la Engine API habilitada, apuntándolo al secreto JWT y a un directorio de datos. Para op-geth, esto normalmente implica flags como --http, --http.api, --authrpc.jwtsecret y --rollup. Para op-reth, existen flags similares. Después de que el cliente de ejecución esté en ejecución, inicia op-node con la URL RPC de L1, la configuración de rollup y el endpoint de la Engine API del cliente de ejecución.
Finalmente, expón el endpoint eth_* del cliente de ejecución para lecturas de dapps. Este es el endpoint que las aplicaciones usarán para consultar la cadena L2. También puedes exponer el endpoint optimism_* de op-node para monitoreo. Asegúrate de que las reglas de tu firewall permitan el acceso a los puertos deseados y de que tengas espacio en disco adecuado para la base de datos de la L2, que puede crecer mucho según la actividad de la cadena.
#!/bin/bash
# Example: Start op-geth and op-node for an OP Stack chain
# Generate JWT secret
openssl rand -hex 32 > jwt.hex
# Start op-geth (execution client)
./op-geth \
--datadir ./datadir \
--http \
--http.addr 0.0.0.0 \
--http.port 8545 \
--http.api eth,net,web3,debug \
--http.corsdomain '*' \
--authrpc.addr 0.0.0.0 \
--authrpc.port 8551 \
--authrpc.jwtsecret ./jwt.hex \
--rollup \
--rollup.sequencerhttp https://mainnet-sequencer.optimism.io \
--syncmode full
# Start op-node (rollup consensus client)
./op-node \
--l1 https://ethereum-rpc.example.com \
--l2 http://localhost:8551 \
--rollup.config ./rollup.json \
--rpc.addr 0.0.0.0 \
--rpc.port 9545 \
--p2p.listen.ip 0.0.0.0 \
--p2p.listen.tcp 9003 \
--p2p.listen.udp 9003 \
--sequencer.enabled=false \
--jwt-secret ./jwt.hexVerificación de la salud del nodo y el progreso de la derivación
Después de iniciar el nodo, debes verificar que se está sincronizando correctamente y que el proceso de derivación es honesto. Comienza llamando a eth_chainId en el endpoint del cliente de ejecución y confirmando que coincide con el ID de cadena L2 previsto. Luego, llama a eth_blockNumber dos veces con un breve retraso para confirmar que la cabeza está avanzando. Si el número de bloque no aumenta, el nodo no se está sincronizando.
A continuación, verifica las etiquetas de bloque seguro y finalizado usando eth_getBlockByNumber con 'safe' y 'finalized'. Estas deberían avanzar a medida que la derivación se pone al día. La cabeza segura representa bloques derivados de lotes de la L1, mientras que la cabeza finalizada representa bloques que también están finalizados en la L1. Si la cabeza segura se queda atrás de la cabeza insegura (la cabeza del secuenciador), indica que op-node no está derivando nuevos bloques, posiblemente debido a un RPC de L1 en mal estado o a un problema de configuración.
Finalmente, consulta optimism_syncStatus de op-node para confirmar que la cabeza de la L2 sigue a la cabeza de derivación de la L1. Este método devuelve información sobre las cabezas actuales de L1 y L2, así como las cabezas segura y finalizada de la L2. Si la cabeza de la L2 está muy por detrás de la cabeza de la L1, la derivación puede estar retrasada. Para obtener una guía detallada sobre el uso de la Engine API para el estado de sincronización, consulta Estado de sincronización del nodo OP Stack a través de la Engine API.
// Node.js script to verify OP Stack node health
const { ethers } = require('ethers');
async function checkHealth() {
const provider = new ethers.JsonRpcProvider('http://localhost:8545');
const opNodeProvider = new ethers.JsonRpcProvider('http://localhost:9545');
// 1. Check chain ID
const chainId = await provider.getNetwork();
console.log('Chain ID:', chainId.chainId);
// 2. Check block number advancement
const block1 = await provider.getBlockNumber();
await new Promise(r => setTimeout(r, 5000));
const block2 = await provider.getBlockNumber();
console.log('Block number:', block1, '->', block2);
if (block2 <= block1) console.warn('Head not advancing!');
// 3. Check safe and finalized blocks
const safe = await provider.getBlock('safe');
const finalized = await provider.getBlock('finalized');
console.log('Safe block:', safe?.number, 'Finalized block:', finalized?.number);
// 4. Check op-node sync status
const syncStatus = await opNodeProvider.send('optimism_syncStatus', []);
console.log('Sync status:', JSON.stringify(syncStatus, null, 2));
}
checkHealth().catch(console.error);Cabezas insegura, segura y finalizada: estrategia de confirmación
OP Stack define tres etiquetas de bloque distintas: insegura, segura y finalizada. La cabeza insegura es el último bloque producido por el secuenciador; aún no se ha derivado de la L1 y podría reorganizarse si el secuenciador se comporta mal. La cabeza segura se deriva de lotes de la L1 y se considera a salvo de reorganizaciones del secuenciador, pero aún podría reorganizarse si la propia L1 se reorganiza. La cabeza finalizada se deriva de bloques de la L1 que están finalizados en Ethereum, lo que la convierte en la más segura pero también la más retrasada.
Al construir aplicaciones, debes elegir una estrategia de confirmación de manera deliberada. Para transacciones de alto valor, esperar la cabeza finalizada proporciona la garantía más fuerte. Para operaciones de menor valor o sensibles al tiempo, la cabeza segura puede ser suficiente. La cabeza insegura solo debe usarse para actualizaciones de UI en tiempo real, no para liquidación. La compensación es entre latencia y seguridad; la cabeza finalizada va por detrás de la cabeza insegura por el tiempo de finalidad de la L1 (normalmente 12-15 minutos en Ethereum).
Puedes consultar estas cabezas usando eth_getBlockByNumber con las etiquetas 'safe' y 'finalized', o usando el método optimism_syncStatus en op-node. Para obtener más información sobre las marcas de tiempo de derivación de la L1, consulta Marca de tiempo de derivación de L1 de OP Stack.
- Insegura: cabeza del secuenciador, no derivada, sujeta a reorganizaciones del secuenciador.
- Segura: derivada de lotes de la L1, a salvo de reorganizaciones del secuenciador, pero no finalizada en la L1.
- Finalizada: derivada de bloques finalizados en la L1, garantía más fuerte, mayor latencia.
- Elige la etiqueta de confirmación según el valor de la transacción y la tolerancia a la latencia.
Autoalojamiento vs endpoints alojados: compensaciones y selección
Ejecutar tu propio nodo OP Stack te da control total, privacidad e independencia de proveedores externos. Sin embargo, requiere recursos significativos: espacio en disco, ancho de banda y mantenimiento continuo. Debes monitorear el nodo, aplicar actualizaciones y gestionar las dependencias del RPC de L1. Para muchos equipos, un endpoint alojado es más práctico, especialmente para desarrollo o aplicaciones de bajo volumen.
Los proveedores de RPC alojados, como OnFinality, ofrecen endpoints de cadenas OP Stack que abstraen la infraestructura del nodo. Obtienes un endpoint eth_* confiable sin ejecutar ningún software. La compensación es que dependes del proveedor para el tiempo de actividad y la precisión de los datos. Para sistemas de producción con altos requisitos de cumplimiento, el autoalojamiento puede ser necesario. Para una comparación de opciones de endpoints, consulta Endpoints RPC de Optimism (RPC Assistant).
Al elegir un proveedor alojado, considera factores como límites de velocidad, métodos admitidos y distribución geográfica. OnFinality ofrece servicio de API con varios planes; puedes revisar precios de RPC para encontrar un nivel adecuado. Para una visión más amplia de las redes, visita el centro de aprendizaje de OnFinality.
- Autoalojamiento: control total, privacidad, pero alta sobrecarga operativa.
- Endpoints alojados: bajo mantenimiento, pero dependencia del proveedor.
- Considera límites de velocidad, soporte de métodos y costo.
- OnFinality ofrece endpoints de cadenas OP Stack con planes flexibles.
Limitaciones y supuestos
Este artículo asume que estás ejecutando un nodo OP Stack completo, no un secuenciador. La operación del secuenciador requiere configuración adicional y no se cubre aquí. También asume que tienes un endpoint RPC de Ethereum L1 confiable; sin él, op-node no puede funcionar. Los requisitos de rendimiento y recursos varían según la cadena y el cliente de ejecución; debes evaluar tu configuración bajo la carga esperada.
OP Stack está en desarrollo activo. Las versiones de los clientes, los flags de configuración y los métodos RPC pueden cambiar. Consulta siempre la documentación oficial para obtener la información más reciente. Los métodos de verificación descritos aquí son reproducibles, pero los resultados exactos dependerán del estado de sincronización de tu nodo y de las condiciones de la red. No proporcionamos números específicos de latencia o rendimiento, ya que dependen del entorno.
Finalmente, este artículo se centra en la arquitectura del cliente y no cubre temas avanzados como instantáneas, poda o configuraciones de rollup personalizadas. Para esos temas, consulta las especificaciones de Optimism y la documentación específica de cada cliente.
- Asume un nodo completo, no un secuenciador.
- Requiere un endpoint RPC de L1 en buen estado.
- Las versiones de los clientes y los flags pueden cambiar; consulta la documentación oficial.
- No se proporcionan números de rendimiento específicos; mide los tuyos.
Guía de resolución de problemas
Si op-node no arranca o no puede conectarse al cliente de ejecución, verifica la autenticación de la Engine API. Asegúrate de que ambos procesos usen el mismo secreto JWT y que el puerto authrpc del cliente de ejecución sea accesible. Los errores comunes incluyen 'invalid jwt' o 'connection refused'. Verifica la ruta y los permisos del archivo JWT.
Si op-node se está ejecutando pero la cabeza de la L2 no avanza, verifica el endpoint RPC de L1. op-node lee la L1 para obtener lotes; si el RPC de L1 no está sano o tiene límite de velocidad, la derivación se detendrá. Prueba el endpoint de L1 con una simple llamada eth_blockNumber. Además, verifica que la configuración de rollup coincida con la cadena que pretendes ejecutar; una discrepancia en el ID de cadena hará que op-node derive la cadena incorrecta.
Si la cabeza segura se queda atrás de la cabeza insegura, significa que op-node no está derivando nuevos bloques seguros. Esto podría deberse a un retraso en el envío de lotes a la L1 o a un problema con el contrato de bandeja de entrada de lotes. Verifica la dirección de la bandeja de entrada de lotes en la configuración de rollup y asegúrate de que coincida con el contrato actual de la cadena. Para obtener más información sobre el manejo de reorganizaciones, consulta Manejo de reorganizaciones en clientes Bor y Erigon.
- Fallos de autenticación de la Engine API: verifica el secreto JWT y el puerto.
- op-node no avanza: verifica la salud del RPC de L1 y la configuración de rollup.
- Cabeza segura atascada: verifica el contrato de bandeja de entrada de lotes y el envío de lotes a la L1.
- Discrepancia de ID de cadena: confirma que la configuración de rollup coincide con la cadena objetivo.
Próximos pasos y recursos adicionales
Una vez que tu nodo esté sincronizado, puedes conectar tu dapp al endpoint eth_* del cliente de ejecución. Para producción, considera configurar monitoreo para la altura de bloque, el número de pares y el retraso de derivación. Puedes usar el método optimism_syncStatus para rastrear el progreso de la derivación. Si prefieres una solución gestionada, explora Endpoints RPC de Optimism (RPC Assistant) o la página de redes de OnFinality.
Para profundizar tu comprensión, revisa las especificaciones de Optimism para obtener detalles sobre la derivación y la arquitectura de nodo de Optimism para obtener orientación operativa. Para temas relacionados con RPC de OP Stack, consulta nuestros artículos sobre Engine API newPayload y forkchoice y Estado de sincronización del nodo OP Stack a través de la Engine API.
Finalmente, mantente actualizado con las versiones de los clientes. Tanto op-geth como op-reth se desarrollan activamente, y las nuevas versiones pueden incluir mejoras de rendimiento y correcciones de errores. Revisa regularmente los repositorios oficiales y actualiza tu nodo para beneficiarte de las últimas características.
- Conecta las dapps al endpoint eth_* del cliente de ejecución.
- Monitorea la altura de bloque, el número de pares y el retraso de derivación.
- Considera endpoints alojados para configuraciones de bajo mantenimiento.
- Mantén los clientes actualizados y consulta la documentación oficial.