Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Infraestructura y operaciones12 min de lectura

eth_syncing y estado de sincronización: verificar un RPC de Ethereum en producción

Aprende qué devuelve realmente eth_syncing, por qué false no prueba que un nodo sea utilizable y cómo construir una aserción de sincronización confiable para un RPC de Ethereum en producción.

TL;DR

eth_syncing devuelve false cuando un nodo no está sincronizando y un objeto con startingBlock, currentBlock y highestBlock cuando sí lo está, pero false no prueba que el nodo sea utilizable ni que esté en la cabeza de la red. Muchos clientes informan false mientras aún están reparando el estado o sincronizando hacia una cabeza conocida, por lo que una verificación de estado basada únicamente en eth_syncing no es sólida. Una aserción confiable combina eth_chainId y net_version para confirmar la cadena, y luego mide el retraso respecto a la cabeza muestreando eth_blockNumber del candidato y de referencias independientes durante una ventana y comparando los deltas. Este artículo proporciona un verificador Node.js ejecutable y una tabla de resultados para verificar tu propio endpoint.

El contrato de valor de retorno de eth_syncing

La especificación de Ethereum JSON-RPC define eth_syncing como el retorno de false cuando el nodo no está sincronizando y un objeto que describe el progreso de sincronización en caso contrario. Ese objeto normalmente incluye startingBlock, currentBlock y highestBlock, pero el conjunto exacto de campos y su precisión varían según el cliente y la versión. Este es un comportamiento documentado, no un error, y significa que cualquier analizador debe manejar dos formas muy diferentes: un booleano y un objeto.

Un cliente ingenuo que trata false como saludable no ha asegurado nada sobre qué estado de la cadena está sirviendo el nodo. El nodo puede estar completamente sincronizado, o puede estar muy atrasado pero no encontrarse actualmente en un bucle de sincronización. El valor de retorno es una bandera de estado, no un veredicto de salud. Para un sistema en producción, necesitas conocer la posición del nodo en relación con la cabeza de la red, no solo si está sincronizando activamente.

La especificación JSON-RPC 2.0 rige el sobre de solicitud y respuesta, incluido el manejo de errores, pero no define la semántica de eth_syncing. La especificación de Ethereum JSON-RPC es la fuente autorizada para el contrato de retorno del método. Consulta siempre la documentación del cliente de ejecución para conocer los campos que realmente devuelve, porque los clientes difieren.

  • false: el nodo informa que no está sincronizando; no implica que esté en la cabeza de la red.
  • Objeto: el nodo informa el progreso de sincronización; los campos varían según el cliente y la versión.
  • Campos comunes: startingBlock, currentBlock, highestBlock (pueden estar ausentes o desactualizados).
  • El análisis debe manejar tanto la forma booleana como la de objeto sin lanzar excepciones.

Por qué eth_syncing puede informar false mientras un nodo está atrasado

La sincronización snap y la sincronización por checkpoint permiten que un nodo sea operativo antes de haber validado completamente el estado histórico. Durante la reparación del estado, el nodo puede informar false porque se considera sincronizado con la cabeza que conoce, aunque todavía esté alcanzando la cabeza de la red. Este es un comportamiento documentado y reportado durante mucho tiempo, visible en rastreadores de problemas públicos y en la documentación de los clientes.

Los clientes también difieren en lo que consideran 'sincronizado'. Algunos informan false una vez que tienen el encabezado del último bloque, incluso si el estado está incompleto. Otros pueden informar false cuando están a una pequeña distancia de la cabeza. El resultado es que eth_syncing por sí solo no puede distinguir un nodo que está completamente al día de uno que simplemente no está en un bucle de sincronización activo.

Para un endpoint RPC en producción, el riesgo es la falsa confianza. Un balanceador de carga puede enrutar a un backend que informa false pero está minutos u horas atrás. Tu aplicación entonces lee datos obsoletos sin error. El único enfoque sólido es medir el retraso respecto a la cabeza directamente, usando comparaciones de eth_blockNumber contra referencias independientes.

  • Sincronización snap/checkpoint: el nodo puede ser operativo antes de la validación completa del estado.
  • Reparación de estado: el nodo puede informar false mientras todavía se pone al día.
  • Las definiciones de 'sincronizado' específicas de cada cliente varían; no asumas uniformidad.
  • Los falsos negativos son el modo de fallo principal de las verificaciones de estado basadas en eth_syncing.

Verificaciones de identidad de cadena antes de comparar alturas

Antes de comparar alturas de bloque, confirma que el nodo está en la cadena esperada. Usa eth_chainId para obtener el ID de cadena y net_version para obtener el ID de red. Estas llamadas son baratas y deberían formar parte de cada verificación de estado. Un nodo en la cadena equivocada tendrá una altura de bloque diferente y podría producir mediciones de retraso engañosas.

Para la red principal de Ethereum, el ID de cadena es 1. Para las redes de prueba, es diferente. Si tu aplicación espera la red principal, un nodo en una red de prueba informará un número de bloque mucho menor y parecerá atrasado. Verificar primero la identidad de la cadena evita falsos positivos y asegura que tus endpoints de referencia estén en la misma cadena.

La guía de endpoints RPC (RPC Assistant) cubre cómo seleccionar y verificar endpoints. Para detalles de red específicos de OnFinality, consulta la página de la red Ethereum.

  • eth_chainId devuelve el ID de cadena (p. ej., 1 para la red principal).
  • net_version devuelve el ID de red (a menudo el mismo que el ID de cadena).
  • Compara siempre el candidato y la referencia en la misma cadena.
  • Los ID de cadena que no coinciden invalidan cualquier comparación de altura.

Medir el retraso respecto a la cabeza con deltas de eth_blockNumber

El retraso respecto a la cabeza es la diferencia entre el último número de bloque del nodo candidato y la cabeza de la red. Para medirlo de forma confiable, muestrea eth_blockNumber del candidato y de al menos dos endpoints de referencia independientes durante una ventana corta. Luego compara los deltas: un nodo en la punta avanza al mismo ritmo que las referencias; un nodo atrasado avanza al mismo ritmo pero con un desfase fijo; un nodo estancado no avanza.

Una sola comparación no es suficiente porque la producción de bloques es irregular. Las diferencias puntuales son ruido. Usa una ventana de varias muestras y calcula la diferencia mediana en lugar de la máxima. La mediana estabiliza la señal y reduce el impacto de los valores atípicos. Una ventana de 5 a 10 muestras durante 30 a 60 segundos suele ser suficiente para una verificación en producción.

El artículo Detectar el retraso respecto a la cabeza y respuestas obsoletas de nodos RPC cubre la detección del lado del cliente con más detalle. Para monitoreo y alertas, consulta Monitoreo de nodos RPC, métricas y alertas.

  • Muestrea el candidato y las referencias durante una ventana (p. ej., 5 a 10 muestras).
  • Calcula la diferencia en cada muestra: altura del candidato menos altura de la referencia.
  • Usa la diferencia mediana como estimación del retraso.
  • Un nodo estancado muestra avance cero entre muestras.
  • Un nodo atrasado muestra un desfase consistente.
  • Un nodo saludable muestra una diferencia cercana a cero (dentro de uno o dos bloques).

Semántica de las etiquetas: latest, safe y finalized

Las etiquetas latest, safe y finalized provienen de lugares diferentes para un mismo cliente, y un cliente puede servir una correctamente y otra desactualizada. latest se refiere al bloque más reciente que conoce el nodo, que puede no ser la cabeza de la red. safe y finalized se refieren a puntos de control de la capa de consenso y pueden ir por detrás de latest. Las verificaciones de estado deben indicar qué etiqueta sondean.

Para sistemas en producción, comparar latest entre el candidato y las referencias es la medida más directa del retraso respecto a la cabeza. Sin embargo, si tu aplicación depende de datos finalizados, también deberías verificar que el bloque finalizado esté avanzando. Un nodo puede estar en la cabeza para latest pero atrasado en finalized si no está recibiendo actualizaciones de consenso.

Documenta qué etiqueta usa tu verificación de estado y asegúrate de que tus endpoints de referencia admitan la misma etiqueta. Mezclar etiquetas entre el candidato y la referencia producirá números de retraso engañosos.

  • latest: bloque más reciente conocido por el nodo; puede no ser la cabeza de la red.
  • safe: bloque reciente considerado seguro por el consenso; puede ir por detrás de latest.
  • finalized: bloque considerado final; va por detrás de latest al menos dos épocas.
  • Indica la etiqueta en tu verificación de estado y úsala de forma consistente.

Límites operativos de los endpoints RPC remotos

Un endpoint RPC que no operas puede estar balanceado entre múltiples backends. Dos sondeos consecutivos pueden no llegar al mismo nodo. Esto hace que la comparación por sondeo sea el único patrón seguro: compara la respuesta del candidato con la respuesta de la referencia en el mismo momento, en lugar de asumir una línea base de larga duración. Una línea base de un sondeo anterior puede reflejar un backend diferente.

Si operas tu propio nodo, puedes mantener una línea base, pero aún deberías muestrear durante una ventana para tener en cuenta la producción irregular de bloques. Para endpoints de terceros, trata siempre cada sondeo como independiente. Las páginas del servicio de API y de precios de RPC describen las ofertas de OnFinality, pero el método de medición se aplica a cualquier proveedor.

El balanceo de carga también significa que una única URL de endpoint puede devolver alturas diferentes en llamadas consecutivas. Tu verificador no debe asumir monotonicidad entre sondeos. En su lugar, compara el candidato y la referencia en el mismo índice de muestra.

  • Los endpoints remotos pueden estar balanceados; los sondeos consecutivos pueden llegar a backends diferentes.
  • Compara el candidato y la referencia en el mismo momento, no contra una línea base histórica.
  • Para nodos autooperados, una línea base es posible, pero igualmente muestrea durante una ventana.
  • No asumas alturas de bloque monotónicas entre sondeos en un endpoint balanceado.

Verificador Node.js ejecutable para la aserción de sincronización

El siguiente script de Node.js sondea un endpoint candidato y dos endpoints de referencia durante una ventana, calcula el retraso mediano e imprime un veredicto. Usa la API fetch nativa (Node.js 18+). Reemplaza las URL de marcador de posición con tus propios endpoints. El script maneja tanto respuestas booleanas como de objeto de eth_syncing por completitud, pero el veredicto se basa en los deltas de eth_blockNumber.

Ejecútalo con: node sync-check.js. El script genera una tabla de muestras y un veredicto final. Usa los resultados para completar la tabla de la siguiente sección.

const CANDIDATE = 'https://your-candidate-rpc';
const REF1 = 'https://reference-1-rpc';
const REF2 = 'https://reference-2-rpc';
const SAMPLES = 7;
const INTERVAL_MS = 5000;

async function rpc(url, method, params = []) {
  const res = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params })
  });
  const json = await res.json();
  if (json.error) throw new Error(json.error.message);
  return json.result;
}

async function getBlockNumber(url) {
  const hex = await rpc(url, 'eth_blockNumber');
  return parseInt(hex, 16);
}

async function getChainId(url) {
  return rpc(url, 'eth_chainId');
}

function median(arr) {
  const sorted = [...arr].sort((a, b) => a - b);
  const mid = Math.floor(sorted.length / 2);
  return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
}

(async () => {
  const chainId = await getChainId(CANDIDATE);
  console.log('Candidate chainId:', chainId);
  const refChainId = await getChainId(REF1);
  if (chainId !== refChainId) {
    console.error('Chain ID mismatch. Aborting.');
    process.exit(1);
  }

  const rows = [];
  for (let i = 0; i < SAMPLES; i++) {
    const [c, r1, r2] = await Promise.all([
      getBlockNumber(CANDIDATE),
      getBlockNumber(REF1),
      getBlockNumber(REF2)
    ]);
    const refMedian = median([r1, r2]);
    const lag = c - refMedian;
    rows.push({ sample: i + 1, candidate: c, ref1: r1, ref2: r2, refMedian, lag });
    console.log(`Sample ${i + 1}: candidate=${c} ref1=${r1} ref2=${r2} refMedian=${refMedian} lag=${lag}`);
    if (i < SAMPLES - 1) await new Promise(r => setTimeout(r, INTERVAL_MS));
  }

  const lags = rows.map(r => r.lag);
  const medianLag = median(lags);
  const maxLag = Math.max(...lags);
  const minLag = Math.min(...lags);
  const candidateAdvance = rows[rows.length - 1].candidate - rows[0].candidate;
  const refAdvance = rows[rows.length - 1].refMedian - rows[0].refMedian;

  console.log('\n--- Summary ---');
  console.log(`Median lag: ${medianLag}`);
  console.log(`Min lag: ${minLag}, Max lag: ${maxLag}`);
  console.log(`Candidate advance: ${candidateAdvance}, Reference advance: ${refAdvance}`);

  let verdict = 'UNKNOWN';
  if (candidateAdvance === 0 && refAdvance > 0) verdict = 'STALLED';
  else if (medianLag > 5) verdict = 'LAGGING';
  else if (Math.abs(medianLag) <= 2) verdict = 'HEALTHY';
  else verdict = 'DEGRADED';
  console.log(`Verdict: ${verdict}`);
})();

Tabla de resultados para tus propias mediciones

Usa la tabla a continuación para registrar tus propias mediciones. Ejecuta el verificador contra tu endpoint candidato y dos referencias, luego completa las columnas. Las columnas de retraso mediano y veredicto deben calcularse a partir de tus muestras. Esta tabla es una plantilla; no trates los valores de ejemplo como mediciones reales.

Después de completar la tabla, compara tus resultados en diferentes momentos del día y con diferentes endpoints. Un endpoint saludable debería mostrar un retraso mediano cercano a cero y un avance consistente. Un endpoint atrasado mostrará un retraso mediano positivo. Un endpoint estancado mostrará avance cero.

  • Muestra: número secuencial del sondeo.
  • Candidato: número de bloque de tu endpoint.
  • Referencia 1 / Referencia 2: números de bloque de endpoints independientes.
  • Mediana de referencia: mediana de las dos alturas de referencia.
  • Retraso: candidato menos la mediana de referencia.
  • Veredicto: HEALTHY, DEGRADED, LAGGING o STALLED según tus umbrales.

Limitaciones y compensaciones

Este método mide el retraso respecto a la cabeza, no el estado completo de sincronización. Un nodo puede estar en la cabeza para latest pero aún estar reparando el estado o faltarle datos históricos. Para aplicaciones que requieren datos de archivo, debes verificar por separado la disponibilidad histórica, como se cubre en Nodo de archivo de Ethereum y RPC histórico.

Los endpoints de referencia no son infalibles. Si ambas referencias están atrasadas o en una bifurcación diferente, tu medición de retraso será incorrecta. Usa al menos dos referencias independientes y considera una tercera para sistemas críticos. El método también asume que la producción de bloques está en curso; en una red de prueba sin bloques recientes, las mediciones de retraso pueden carecer de sentido.

El verificador usa eth_blockNumber, que devuelve el último número de bloque. No verifica que el bloque sea canónico ni que el estado esté disponible. Para una verificación de estado completa, combina esto con el análisis de eth_syncing, la verificación del ID de cadena y pruebas de lectura a nivel de aplicación. El centro de aprendizaje de OnFinality tiene guías relacionadas sobre monitoreo y detección.

  • Mide el retraso respecto a la cabeza, no la sincronización completa ni la disponibilidad del estado.
  • Requiere al menos dos referencias independientes.
  • Asume producción activa de bloques en la cadena.
  • No verifica la canonicalidad ni los datos históricos.
  • Combínalo con pruebas de lectura a nivel de aplicación para una cobertura completa.

Solución de problemas comunes en las aserciones de sincronización

Si tu verificador informa un retraso grande pero el nodo parece saludable en otras herramientas, verifica que todos los endpoints estén en la misma cadena. Una discrepancia en el ID de cadena producirá un desfase consistente. También comprueba que estás comparando la misma etiqueta; si el candidato usa latest y la referencia usa finalized, el retraso será grande y esperado.

Si el verificador informa STALLED, confirma que los endpoints de referencia estén avanzando. Si las referencias también están estancadas, la cadena puede estar detenida o tus referencias pueden estar caídas. Si solo el candidato está estancado, el nodo puede estar desconectado de sus pares o experimentando un problema de consenso. Revisa el número de pares y los registros del nodo.

Si el verificador informa HEALTHY pero tu aplicación ve datos obsoletos, el problema puede ser la reparación del estado o la disponibilidad de datos de archivo, no el retraso respecto a la cabeza. Usa eth_getBlockByNumber con un bloque reciente para verificar el estado, y considera un endpoint de archivo dedicado. La guía Estado de sincronización de nodo Base OP-Stack cubre conceptos similares para cadenas OP-Stack.

  • Discrepancia de ID de cadena: verifica eth_chainId en todos los endpoints.
  • Discrepancia de etiqueta: asegúrate de que el candidato y las referencias usen la misma etiqueta.
  • Referencias estancadas: revisa la salud de las referencias y el estado de la cadena.
  • Candidato estancado: revisa el número de pares y los registros del nodo.
  • Cabeza saludable pero datos obsoletos: revisa la reparación del estado y la disponibilidad de archivo.

Próximos pasos para el monitoreo de sincronización en producción

Integra el verificador en tu canal de monitoreo. Ejecútalo según una programación (p. ej., cada minuto) y alerta cuando el retraso mediano supere un umbral. Almacena los resultados para rastrear tendencias a lo largo del tiempo. Combínalo con el análisis de eth_syncing para obtener una imagen completa, pero no dependas solo de eth_syncing.

Para endpoints específicos de OnFinality, consulta la página de la red Ethereum y los precios de RPC. El servicio de API proporciona endpoints RPC gestionados que puedes verificar con este método. Para más guías, visita el centro de aprendizaje de OnFinality.

Recuerda que el conjunto exacto de campos y la precisión de eth_syncing varían según el cliente y la versión. Prueba siempre contra tu cliente y versión específicos. El método descrito aquí es agnóstico al cliente y se basa en eth_blockNumber, que es ampliamente compatible.

  • Programa el verificador y alerta según umbrales de retraso mediano.
  • Almacena los resultados para el análisis de tendencias.
  • Combínalo con el análisis de eth_syncing y las verificaciones de ID de cadena.
  • Prueba contra tu cliente y versión específicos.
  • Revisa las guías relacionadas sobre monitoreo y detección.

Nunca te preocupes por la infraestructura nuevamente

OnFinality elimina la carga pesada de DevOps para que puedas construir de forma más inteligente y rápida.

Comenzar