Las reorganizaciones de Polygon PoS no son simplemente reorganizaciones de Ethereum más superficiales: Bor rota los productores de bloques por sprint, y la finalidad está anclada por checkpoints de Heimdall que aterrizan en Ethereum L1, por lo que un bloque puede ser canónico en Bor pero aún no estar anclado por checkpoint. La forma fiable de detectar una reorganización vía RPC es usar el hash de bloque como clave en lugar de la altura, releer la cabeza en cada sondeo y retroceder por parentHash hasta reconectar con un hash canónico almacenado, reportando la profundidad y el punto de bifurcación. La elección de cliente importa porque Bor (el cliente de ejecución actualmente recomendado por Polygon tras la migración de Erigon a Bor) y el Erigon heredado o cdk-erigon exponen superficies de métodos que se solapan pero no son idénticas, por lo que un indexador que depende de un método específico de un cliente puede romperse cuando el endpoint es servido por un cliente diferente. El diseño seguro se basa en la superficie estándar eth_* más la capa de checkpoints, y contrasta una reorganización sospechada con el estado de checkpoints de Heimdall para distinguir una reorganización real de un desacuerdo entre dos endpoints.
Perfil de reorganización de Polygon PoS frente a Ethereum L1
En Ethereum L1, se selecciona un único proponente por slot, por lo que una bifurcación producida por un validador tiene una forma predecible: el conjunto revertido está acotado por cuántos slots controló ese proponente antes de que el siguiente proponente honesto extendiera una cadena competidora. Polygon PoS cambia esa forma porque Bor rota los productores de bloques por sprint en lugar de por slot. Un span selecciona un subconjunto de validadores, y dentro de ese span los productores rotan en cada sprint, por lo que el conjunto de bloques que un solo productor puede revertir tiene un límite diferente al modelo de Ethereum L1. La documentación de Polygon sobre consenso Bor describe los sprints y spans y esta rotación de productores como el núcleo de la producción de bloques de Bor.
La segunda diferencia es el anclaje de finalidad. Heimdall confirma periódicamente el estado de Bor en Ethereum L1 como checkpoints, por lo que un bloque puede ser canónico en Bor pero aún no estar anclado por checkpoint. Esa brecha es la ventana en la que todavía puede ocurrir una reorganización. En la práctica, esto significa que un indexador de Polygon debe tener en cuenta dos capas a la vez: la capa de ejecución de Bor (bloques, recibos, estado) y la capa de Heimdall/checkpoints (anclas de finalidad). Confundir 'el bloque está en Bor' con 'el bloque está finalizado' es la raíz de la mayoría de los errores de indexadores en Polygon. Para obtener más detalles sobre la mecánica de rotación de productores, consulta Sprints, spans y conjuntos de validadores de Polygon Bor.
- Bor rota los productores por sprint dentro de un span, por lo que la bifurcación de un solo productor tiene un perfil de profundidad diferente al de una bifurcación basada en slots de Ethereum L1.
- Los checkpoints de Heimdall anclan el estado de Bor a Ethereum L1; hasta que un bloque está anclado por checkpoint, sigue siendo elegible para reorganización.
- Trata 'canónico en Bor' y 'finalizado' como estados separados, no como sinónimos.
El modelo de dos capas: ejecución de Bor y checkpoints de Heimdall
La capa de ejecución de Bor es lo que expone un endpoint JSON-RPC estándar de Ethereum: eth_getBlockByNumber, eth_getBlockByHash, eth_getBlockReceipts, eth_getLogs y los módulos de trazas donde el cliente los soporte. La capa de Heimdall/checkpoints es una superficie separada que informa qué bloques de Bor se han confirmado en Ethereum L1. Estas dos capas se consultan a través de endpoints diferentes y espacios de nombres de métodos diferentes, y se actualizan con cadencias diferentes. Un indexador que solo lee la capa de Bor puede observar un bloque, indexarlo y luego descubrir que fue reorganizado antes de que ningún checkpoint lo anclara.
La consecuencia práctica es que tu detector de reorganizaciones debe ejecutarse en la capa de Bor, pero tu confirmación de finalidad debe consultar la capa de checkpoints. Cuando aparece una reorganización sospechada, la capa de checkpoints te dice si la altura afectada ya estaba anclada. Si estaba anclada, es más probable un desacuerdo entre dos endpoints que una reorganización real; si no estaba anclada, una reorganización real es plausible. Esta verificación cruzada es lo que separa una reorganización genuina de un endpoint que simplemente está retrasado o sirviendo una cabeza obsoleta. El artículo Detección de reorganizaciones de bloques de Ethereum vía RPC cubre el patrón de detector de L1 que este diseño específico de Polygon extiende.
- Capa Bor: métodos eth_* para bloques, recibos, logs y trazas.
- Capa Heimdall/checkpoints: informa qué alturas de Bor están ancladas a Ethereum L1.
- Usa la capa de Bor para detectar, la capa de checkpoints para confirmar.
Detección de reorganizaciones basada en hash con recorrido de parentHash
La especificación JSON-RPC de Ethereum define eth_getBlockByNumber y eth_getBlockByHash como métodos que devuelven un bloque cuyo parentHash lo enlaza con su predecesor, y ambos devuelven null para un bloque desconocido. Ese enlace parentHash es la primitiva que debe usar un detector de reorganizaciones. Usar el hash de bloque como clave en lugar de la altura evita el error clásico en el que una altura es reutilizada por un bloque diferente tras una reorganización, corrompiendo silenciosamente un índice que almacena la altura como clave primaria. La referencia de la especificación para este comportamiento es la documentación de eth_getBlockByHash de Ethereum JSON-RPC.
Un detector acotado funciona de la siguiente manera: en cada sondeo, vuelve a leer la cabeza, compara su hash con el último hash canónico almacenado y, si difieren, retrocede por parentHash desde la nueva cabeza hasta reconectar con un hash canónico almacenado. La diferencia de altura entre el punto de reconexión y la cabeza antigua es la profundidad de la reorganización, y el bloque de reconexión es el punto de bifurcación. Acota el recorrido con una profundidad máxima para que un endpoint patológico o mal configurado no pueda hacer que el detector entre en bucle indefinidamente. El código a continuación es un detector mínimo en Node.js que usa la superficie estándar eth_*.
const MAX_DEPTH = 128;
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 detectReorg(url, storedCanonical) {
// storedCanonical: Map<height, hash> of blocks you consider canonical
const head = await rpc(url, 'eth_getBlockByNumber', ['latest', false]);
if (!head) return { status: 'no-head' };
let cursor = head;
let depth = 0;
while (cursor && depth <= MAX_DEPTH) {
const height = parseInt(cursor.number, 16);
const known = storedCanonical.get(height);
if (known && known === cursor.hash) {
return {
status: depth === 0 ? 'no-reorg' : 'reorg',
depth,
forkPointHeight: height,
forkPointHash: cursor.hash,
newHead: head.hash
};
}
if (!cursor.parentHash || /^0x0+$/.test(cursor.parentHash)) break;
cursor = await rpc(url, 'eth_getBlockByHash', [cursor.parentHash, false]);
depth += 1;
}
return { status: 'unresolved', depth };
}
module.exports = { detectReorg };Panorama de clientes: Bor, Erigon heredado y cdk-erigon
Polygon ha estado migrando de Erigon a Bor como cliente de ejecución recomendado, y cdk-erigon existe para cadenas CDK. La primera página de resultados de búsqueda para el manejo de reorganizaciones en Polygon está dominada por superficies de migración de clientes y notas de versión, lo que indica que la siguiente pregunta del lector es '¿qué cliente, y qué significa eso para mis datos?'. Bor y el Erigon heredado o cdk-erigon exponen superficies de métodos y módulos de trazas que se solapan pero no son idénticos. Un indexador que depende de un método específico de un cliente se romperá cuando el endpoint sea servido por un cliente diferente, incluso si los datos de la cadena son idénticos.
El diseño seguro se basa en la superficie estándar eth_* más la capa de checkpoints, y trata las extensiones específicas de cada cliente como 'documentadas / varían según el cliente'. Si debes usar un método de traza o depuración, detecta el cliente al inicio y falla de forma ruidosa en lugar de degradarte silenciosamente. Cuando compares endpoints, se aplica el patrón Consistencia multi-endpoint RPC y retraso de cabeza: dos endpoints pueden discrepar en la cabeza sin que ninguno esté equivocado, y ese desacuerdo no es una reorganización. Para obtener contexto a nivel de proveedor sobre endpoints de Polygon, consulta la guía de proveedores RPC de Polygon.
- Bor es el cliente de ejecución actualmente recomendado por Polygon; Erigon heredado y cdk-erigon permanecen en el ecosistema.
- Las superficies de métodos se solapan pero no son idénticas; los módulos de traza y depuración varían según el cliente.
- Detecta el cliente al inicio y falla de forma ruidosa ante métodos faltantes en lugar de degradarte silenciosamente.
Verificación cruzada de checkpoints: reorganización real frente a desacuerdo entre endpoints
Un desacuerdo entre dos endpoints no es automáticamente una reorganización. Un endpoint puede estar retrasado, sirviendo una cabeza obsoleta o temporalmente particionado. La capa de checkpoints te da un desempate: si la altura afectada ya está anclada por checkpoint en Heimdall, una reorganización real a esa altura es implausible, y la explicación más probable es una inconsistencia entre endpoints. Si la altura aún no está anclada, una reorganización real sigue siendo posible y debes confiar en el recorrido basado en hash por encima de la cabeza de cualquier endpoint individual.
La verificación cruzada debe ser parte de la salida del detector, no un paso manual. Cuando el detector reporta una reorganización, registra si la altura del punto de bifurcación estaba anclada por checkpoint en el momento de la detección. Con el tiempo, ese campo te dice si tus reorganizaciones observadas se agrupan en la ventana no anclada, que es exactamente donde el modelo de dos capas predice que deberían estar. Este es también el campo que distingue una reorganización genuina de un artefacto de retraso de cabeza del lado del proveedor cuando comparas múltiples endpoints.
- Altura anclada + desacuerdo entre endpoints: sospecha inconsistencia entre endpoints, no una reorganización.
- Altura no anclada + discrepancia de hash: una reorganización real es plausible.
- Registra el indicador de anclado/no anclado en cada reorganización detectada.
Medición reproducible: completar una tabla de resultados con tu endpoint
Dado que el comportamiento de las reorganizaciones depende de tu endpoint, tu cadencia de sondeo y las condiciones de la red en ese momento, la única forma honesta de caracterizarlo es medirlo tú mismo. Ejecuta el detector anterior contra tu propio endpoint a un intervalo fijo, registra cada evento de reorganización con su profundidad, punto de bifurcación e indicador de anclado, y agrega durante una ventana que elijas. No te bases en ninguna cifra publicada de latencia, rendimiento o tasa, incluidas las que puedan aparecer en material de proveedores; mide contra el endpoint que realmente usas.
La tabla a continuación es una plantilla. Completa la columna 'Observado' con tus propios registros. La columna 'Comportamiento documentado' indica lo que respalda la documentación del protocolo o del cliente, para que puedas distinguir una medición de una suposición. Mantén la ventana y el intervalo de sondeo fijos en todas las filas para que la comparación sea significativa.
Para hacer concreta la medición, el siguiente comando curl obtiene el último bloque de tu endpoint. Ejecútalo con la misma cadencia que tu detector y registra el hash y el número devueltos; comparar hashes sucesivos a la misma altura es la forma más sencilla de detectar una reorganización en la salida RPC sin procesar. La salida esperada es un objeto JSON con campos que incluyen number (altura en hexadecimal), hash y parentHash; si la llamada devuelve null, el endpoint no tiene cabeza que servir y debes tratarlo como un problema del endpoint en lugar de una reorganización.
- Métrica: profundidad de reorganización observada (bloques) — Comportamiento documentado: acotada por la rotación de productores por sprint y por el anclaje de checkpoints; Observado: completar con tus registros.
- Métrica: altura del punto de bifurcación relativa a la cabeza — Comportamiento documentado: el recorrido de parentHash reconecta en el punto de bifurcación; Observado: completar con tus registros.
- Métrica: indicador de anclado en la detección — Comportamiento documentado: las alturas no ancladas son elegibles para reorganización; Observado: completar con tus registros.
- Métrica: recuento de desacuerdos entre endpoints — Comportamiento documentado: no equivale a una reorganización; Observado: completar con tus registros.
- Métrica: tasa de no resueltos del detector — Comportamiento documentado: acotada por MAX_DEPTH; Observado: completar con tus registros.
curl -s -X POST https://your-polygon-rpc-endpoint \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["latest",false]}'Cadencia de sondeo, relecturas de cabeza y recorridos acotados
El detector debe releer la cabeza en cada sondeo en lugar de almacenarla en caché, porque la cabeza es la única señal fiable de que puede haber ocurrido una reorganización. Almacenar la cabeza en caché y comparar solo alturas pasará por alto reorganizaciones en las que la altura se reutiliza. El recorrido de parentHash debe estar acotado por una profundidad máxima que elijas según tu tolerancia al riesgo y tu ventana de observación; si el recorrido supera el límite, reporta 'unresolved' en lugar de adivinar. Un resultado no resuelto es una señal para inspeccionar el endpoint, no una reorganización.
La cadencia de sondeo interactúa con la detección de reorganizaciones: un sondeo muy lento puede saltarse por completo una reorganización corta, mientras que un sondeo muy rápido aumenta la carga y puede alcanzar límites de tasa. No existe una cadencia correcta universal, y cualquier número específico sería una elección específica del proveedor o de la carga de trabajo. Elige una cadencia, mantenla fija durante una ventana de medición y regístrala junto con tus resultados para que los números sean interpretables. El centro de aprendizaje de OnFinality recopila patrones de fiabilidad relacionados si quieres comparar cadencias entre cadenas.
- Vuelve a leer la cabeza en cada sondeo; nunca compares solo alturas.
- Acota el recorrido de parentHash y reporta 'unresolved' cuando se supere el límite.
- Fija la cadencia de sondeo durante una ventana de medición y regístrala con los resultados.
Limitaciones y compensaciones de la detección basada en hash
La detección basada en hash con recorrido de parentHash es robusta pero no gratuita. Requiere almacenar un hash canónico por altura, lo que crece con tu ventana de retención, y requiere una llamada adicional a eth_getBlockByHash por cada paso del recorrido. En una reorganización profunda, el coste del recorrido escala con la profundidad, por lo que el límite MAX_DEPTH también es un límite de coste. Si tu ventana de retención es corta, puedes reconectar rápidamente pero pierdes la capacidad de detectar reorganizaciones profundas; si es larga, pagas más almacenamiento y más pasos de recorrido.
La verificación cruzada de checkpoints añade una dependencia de una segunda superficie, que es una segunda cosa que puede fallar o retrasarse. Trata un fallo de la capa de checkpoints como 'desconocido', no como 'anclado' o 'no anclado'. Por último, los métodos específicos de cada cliente son un riesgo de portabilidad: cualquier detector que dependa de una extensión de traza o depuración está atado al cliente que la sirve. La superficie estándar eth_* más la capa de checkpoints es el subconjunto portátil, y es el subconjunto que usa este diseño. Para necesidades de datos históricos que van más allá de la ventana de reorganización, consulta Nodos de archivo de Polygon y RPC histórico.
- El almacenamiento crece con la ventana de retención; el coste del recorrido crece con la profundidad de la reorganización.
- Un fallo de la capa de checkpoints debe tratarse como 'desconocido', no como una señal de finalidad.
- Los métodos específicos de cada cliente reducen la portabilidad; prefiere la superficie estándar eth_*.
Solución de problemas comunes en la detección de reorganizaciones
El fallo más común es la indexación basada en altura, donde una reorganización reutiliza una altura y el índice sobrescribe o duplica datos silenciosamente. La solución es usar el hash como clave y almacenar la altura como atributo, no como clave primaria. El segundo fallo más común es tratar un desacuerdo entre dos endpoints como una reorganización; la solución es la verificación cruzada de checkpoints descrita anteriormente. El tercero es un recorrido de parentHash sin límite que entra en bucle o agota el tiempo en un endpoint con mal comportamiento; la solución es MAX_DEPTH más un estado 'unresolved'.
Un cuarto fallo es la deriva silenciosa de cliente: un endpoint que servía Bor comienza a servir un cliente diferente, y un método específico de cliente desaparece. La solución es la detección de cliente al inicio y un fallo ruidoso ante métodos faltantes. Un quinto es el almacenamiento en caché de una cabeza obsoleta, donde el detector compara contra una cabeza en caché y pasa por alto reorganizaciones; la solución es releer la cabeza en cada sondeo. Cada uno de estos fallos es observable en la tabla de resultados si registras los campos correctos.
- Índice basado en altura: cambia a almacenamiento basado en hash.
- Desacuerdo entre dos endpoints: añade la verificación cruzada de checkpoints.
- Recorrido sin límite: añade MAX_DEPTH y un estado 'unresolved'.
- Deriva de cliente: detecta el cliente al inicio y falla de forma ruidosa.
- Cabeza obsoleta: vuelve a leer la cabeza en cada sondeo.
Próximos pasos: reforzar un indexador de Polygon
Comienza ejecutando el detector contra tu propio endpoint y completando la tabla de resultados durante una ventana fija. Luego añade la verificación cruzada de checkpoints y el indicador de anclado a tus registros, y vuelve a ejecutar la ventana para poder comparar. Una vez que tengas una línea base, decide tu ventana de retención y MAX_DEPTH en función de las profundidades observadas, no de una suposición. Si necesitas orientación a nivel de proveedor sobre endpoints de Polygon, la guía de proveedores RPC de Polygon y la página de la red Polygon son los puntos de partida.
Para producción, combina el detector con una verificación de consistencia multi-endpoint para que un único endpoint retrasado no pueda hacerse pasar por una reorganización, y revisa Precios de RPC y el Servicio de API si estás dimensionando la capacidad de endpoints. Los patrones de fiabilidad más amplios están en el centro de aprendizaje de OnFinality, y el patrón de detector de L1 que este diseño de Polygon extiende está en Detección de reorganizaciones de bloques de Ethereum vía RPC.
- Ejecuta el detector, completa la tabla de resultados y luego añade la verificación cruzada de checkpoints.
- Elige la ventana de retención y MAX_DEPTH a partir de las profundidades observadas, no de suposiciones.
- Combina el detector con verificaciones de consistencia multi-endpoint para producción.