Saltar al contenido
0%

Cómo reconstruimos los logs históricos para mejorar la velocidad

Autor: Alchemy

Última actualización: 27 de julio de 20266 min de lectura
Cómo reconstruimos los logs históricos para mayor velocidad

Pregúntale a cualquier equipo que esté construyendo un indexador, un agregador de DEX o un sistema de monitoreo onchain dónde se ralentiza su aplicación, y la respuesta es casi siempre la misma: eth_getLogs de rango amplio.

Es la llamada que escanea miles o cientos de miles de bloques para responder una sola pregunta. ¿Qué transfers afectaron a este contrato el mes pasado? ¿Qué pools cambiaron de estado en este rango? ¿Qué eventos se dispararon para esta dirección desde su lanzamiento? Estas lecturas son la columna vertebral de las aplicaciones reales, y también son las que más probablemente se estanquen. Por eso reconstruimos el motor que las atiende, y logramos que el método fuera más de 2x más rápido en p99 en todas las regiones. Así lo hicimos.

¿Qué es eth_getLogs y por qué importa?

eth_getLogs es el método JSON-RPC que devuelve los eventos que emiten los smart contracts mientras se ejecutan: un transfer de tokens, un swap, una aprobación, o cualquier evento personalizado que defina un contrato. Filtras por dirección de contrato, por firma de evento o valores de topics indexados (como Transfer o Approval), y por un rango de bloques con un fromBlock y un toBlock. En términos simples: le dices qué buscar y hasta dónde retroceder, y te devuelve cada evento que coincida.

Esta es la base de la indexación basada en eventos en Ethereum. Sin ella, tendrías que escanear cada transacción a mano para encontrar las que te interesan. Con ella, construyes feeds de actividad y transfers, monitoreo de aprobaciones, y cualquier indexador de eventos en tiempo real o histórico. Es uno de los métodos más usados y operativamente críticos que servimos. Si eres nuevo en logs y topics, nuestra guía a fondo sobre eth_getLogs recorre la estructura de la solicitud y la respuesta con un ejemplo trabajado.

El resto del método define el problema de ingeniería. Muchos proveedores limitan cuántos bloques puedes consultar a la vez. Los indexadores tienen que manejar reorgs de la cadena esperando confirmaciones. Los filtros de topics solo coinciden con campos indexados, así que los argumentos no indexados se decodifican a partir del dato crudo. Y las llamadas cerca del head de la cadena son sensibles a la latencia, donde enrutar al tipo de nodo equivocado puede causar errores o respuestas vacías.

La parte que más define la latencia es el tamaño del rango. Pedir un solo bloque es instantáneo. Para un indexador que reproduce el historial, o un monitor que vigila un contrato durante semanas, los rangos se vuelven amplios rápido, y el costo de la consulta crece con ellos. Ahí es donde la latencia deja de ser un error de redondeo y empieza a limitar qué tan rápido puede construir un cliente.

Todos ofrecen el método. Pocos hablan del motor que hay debajo, porque reconstruir ese motor es costoso y la mayoría de los proveedores no lo ha hecho.

¿Por qué la latencia p99 importa más que la latencia promedio?

El número que duele no es el promedio. Es el p99: ordena cada solicitud de la más rápida a la más lenta, y el p99 es la más lenta de cada cien. Los promedios lo ocultan. Puedes servir 99 solicitudes en 60 milisegundos y aun así ver que la centésima tarda un segundo completo.

Esa solicitud más lenta es la que hace que un dashboard se congele o que un indexador se atrase respecto a la cadena, y es la que tu usuario está mirando. La latencia promedio puede verse bien mientras la cola silenciosamente rompe la carga de trabajo. Para los equipos que operan indexadores y monitores, la cola es la carga de trabajo.

¿Cómo optimizamos eth_getLogs?

Reconstruimos el motor de almacenamiento y consultas que atiende el método, en lugar de ajustar el que ya teníamos.

Hay varias formas de hacer una llamada como esta más rápida. Puedes ajustar parámetros de consulta, agregar una caché, limitar los rangos que aceptas, o agregar más del mismo hardware. La mayoría de esas opciones compran un poco de margen sin cambiar los fundamentos.

Fuimos más profundo. En lugar de depender de una base de datos administrada de propósito general que trata las lecturas de logs históricos como cualquier otra carga de trabajo, operamos una capa de almacenamiento y consultas ajustada específicamente para el patrón de acceso de getLogs: escaneos filtrados rápidos sobre conjuntos de datos muy grandes, en infraestructura dedicada que operamos nosotros mismos.

No ajustamos una perilla ni le pegamos una caché al sistema anterior. Invertimos a nivel de método, en el motor que hay detrás de una de las llamadas más críticas que hacen nuestros clientes. Es trabajo de infraestructura costoso y específico por método, y por eso la mejora se nota en la cola, no solo en el promedio.

¿Cuáles son los resultados?

El titular es simple: más de 2x más rápido en p99, en todas las regiones.

Si operas un indexador o un monitor, el p99 es la latencia que rompe tu carga de trabajo. Un mejor promedio está bien. Una mejor cola es lo que mantiene un dashboard responsivo y un indexador al día con la cadena.

Los equipos que operan esto a gran escala ya lo están viendo. Uno de los exchanges de cripto más grandes comparó sus lecturas de logs históricos en nuestro motor contra operar sus propios nodos, y midió una gran mejora en p99 en su propia carga de trabajo. Esa es una prueba en producción, con la instrumentación propia de un cliente, no solo en nuestros dashboards.

¿Qué significa esto para ti?

Si tu aplicación depende de lecturas de logs históricos para indexar, agregar o monitorear, obtienes lecturas más rápidas y una cola p99 dramáticamente mejor, en todas las regiones, en infraestructura que reconstruimos específicamente para este método. Algunas cosas que vale la pena saber al ponerlo en práctica:

  1. En los planes pay-as-you-go y enterprise, eth_getLogs admite rangos de bloques ilimitados en una sola consulta en Ethereum, Base, Optimism, Arbitrum, Polygon, Robinhood y otras chains importantes, así que reproducir el historial no requiere paginación hecha a mano.
  2. Para logs en el head de la cadena, las suscripciones WebSocket te envían los nuevos logs a medida que llegan, así reservas eth_getLogs para las lecturas históricas para las que está diseñado.
  3. Nada de tu integración cambia. Es el mismo método, la misma forma de solicitud, servida por un motor más rápido.

El sentido de invertir a nivel de método es que las lecturas que definen tu carga de trabajo son las mismas para las que ajustamos el motor. Crea una cuenta gratuita de Alchemy y apunta tu indexador hacia nosotros para ver la diferencia con tu propia instrumentación.

Preguntas frecuentes

¿Qué devuelve eth_getLogs?

Un arreglo de logs de eventos que coinciden con tu filtro: dirección de contrato, firma de evento y valores de topics indexados, y un rango de bloques. Cada log incluye la dirección emisora, los topics, el payload de datos, y el bloque y la transacción de origen. Consulta la referencia de la API para la especificación completa de solicitud y respuesta.

¿Por qué la latencia p99 es más importante que la latencia promedio para los indexadores?

Porque un indexador procesa solicitudes en secuencia o en lotes, las solicitudes más lentas marcan el ritmo. Un promedio bajo con una cola larga significa que el indexador se estanca regularmente en ese uno por ciento lento, se atrasa respecto al head de la cadena, y sirve datos desactualizados. El p99 mide exactamente esas solicitudes.

¿Qué rangos de bloques puedo consultar en una sola llamada a eth_getLogs en Alchemy?

En el tier gratuito, 10 bloques por consulta. En los planes pay-as-you-go y enterprise, los rangos de bloques son ilimitados en Ethereum, Base, Optimism, Arbitrum, Polygon, Worldchain, BNB, y varias otras chains, con respuestas limitadas a 150MB. La tabla completa por chain está en la referencia de eth_getLogs.

¿Cómo mantengo rápidas las consultas históricas amplias?

Filtra lo más ajustado posible: especifica la dirección del contrato y los topics de evento que necesitas, no solo un rango de bloques. Para rangos muy amplios en chains sin soporte de rango ilimitado, divide la consulta en partes más pequeñas. Y para los logs nuevos que se generen en adelante, usa suscripciones WebSocket en lugar de hacer polling.

Boletín de Alchemy

Entérate primero de los lanzamientos

Suscríbete a nuestro boletín

Recibe las últimas actualizaciones de productos y recursos de Alchemy

A
O
D
+
Más de 80,000 suscriptores

Al ingresar tu correo electrónico, aceptas recibir nuestras comunicaciones de marketing y actualizaciones de productos. Reconoces que Alchemy procesa la información que recibimos de acuerdo con nuestro Aviso de Privacidad. Puedes cancelar tu suscripción en cualquier momento.