Tiempo de espera de filtrado de eventos Web3

Este es el código que uso para obtener todos los eventos de un determinado contrato.

Solidez:

event NewEvent(address indexed contractAddress, address newBOPAddress, address payer, uint commitThreshold, bool hasDefaultRelease, uint defaultTimeoutLength, string initialPayerString);

código web3:

event = Factory.contractInstance.NewBOP({contractAddress:'0x384da3....'},{"fromBlock": 0, "toBlock": 'latest'});

event.get(function(err, res) {
  if(err){
    console.log(err.message);
  }
  else{
    console.log(res);
  }
});

Si especifico un fromBlock que es relativamente joven, obtengo una respuesta rápida y todo funciona bien, si uso un bloque que tiene alrededor de 200,000 bloques en el pasado, aparece este error de tiempo de espera:

Tiempo de espera de la puerta de enlace. La solicitud tardó demasiado en procesarse. Esto puede suceder cuando se consultan registros en un rango de bloques demasiado amplio.

Probé esto en ropsten con diferentes nodos (metamask, myetherapi, infura) pero siempre tengo el mismo problema. Adquirí un nodo privado con quicknode.io , que no resuelve el problema, para usuarios que necesitan usar nodos públicos. Sé que podría usar un "fromBlock" más nuevo, pero me gustaría usar los eventos de mi contrato de fábrica como datos históricos, para poder mostrárselos al usuario. Y encontré algunas fuentes que respaldan que es técnicamente posible, especialmente con argumentos indexados para filtrar:

https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e (parte 3)

¿Cómo acceder al registro de eventos conociendo la dirección del contrato (web3)? (utiliza diferentes opciones de filtro)

Mi pregunta exacta es: ¿Necesito un nodo privado completo en todos los casos para el rendimiento deseado, o hay otras razones/formas de hacer que el filtrado de eventos sea más rápido (para detener el tiempo de espera)?

¡Gracias por cualquier respuesta!

Tengo el mismo problema, encontraste alguna forma de solucionarlo? ¡Gracias!

Respuestas (2)

Incluso con un nodo privado, no creo que esto funcione. Blockchain no es tan consultable como una base de datos relacional o no relacional. Su objetivo principal es mantener la consistencia y un estado global en cada bloque, no el rendimiento al leer eventos pasados. Entonces, su opción es usar la paginación e iterar usando fromBlock y toBlock con una diferencia de digamos 1000 hasta llegar al último bloque. Pero si desea mostrar esto a un usuario, aún llevará algún tiempo, por lo que mi recomendación es obtener los datos mediante la paginación y almacenarlos en una base de datos. Luego, en su aplicación de usuario, simplemente consulte desde la base de datos.

¿Necesito un nodo privado completo en todos los casos para el rendimiento deseado, o hay otras razones/formas de hacer que el filtrado de eventos sea más rápido (para detener el tiempo de espera)?

Para el rendimiento crítico en situaciones como esta.

  • Mantiene su propia base de datos centralizada, por ejemplo, SQL

  • Esta base de datos ofrece consultas para los eventos dentro de cualquier criterio de rendimiento que desee.

  • La base de datos se rellena con los eventos pasados

  • Un demonio en vivo lee todos los bloques entrantes nuevos y agrega eventos de ellos a la base de datos

Como se describe en las respuestas, el nodo Ethereum no está optimizado para consultas críticas de rendimiento y es mejor que lo haga usted mismo.

Algún código de Python que lee eventos del nodo Ethereum y llena la base de datos SQL con ellos