Obtener el último resultado de eth_call de un grupo de nodos

¿Cuál es la mejor manera de saber el número de bloque asociado con el resultado de un eth_call? Supongamos que tengo varios nodos que estoy ejecutando y estoy haciendo llamadas a todos ellos (por redundancia). Mi objetivo es obtener el resultado más reciente de un eth_call y maximizar la probabilidad de que sea preciso.

Opción 1.) Puedo hacer una llamada para eth_blockNumber con el parámetro 'latest' y luego una llamada separada para mi eth_call también con el parámetro 'latest', pero no tengo ninguna garantía de que el número de bloque no haya cambiado en ese momento se realizó la llamada eth_call.

payload = {
        "id": randint(0, 99999999999999),
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "data": <DataGoesHere>,
                "to": <ContractAddressGoeshere>
            },
            "latest"
        ]
    }

Opción 2.) O puedo especificar el número de bloque específico en mi eth_call pero eso parece un poco tonto porque tengo que adivinar cuál es el último número de bloque. Tonto porque un nodo puede estar unas pocas cuadras atrás y puede alcanzarlo en cualquier momento. Puedo obtener el número de bloque actual y luego, en paralelo, hacer llamadas para actual + 1 y actual + 2 en caso de que otro bloque o dos se extraigan rápidamente.

payload = {
        "id": randint(0, 99999999999999),
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "data": <DataGoesHere>,
                "to": <ContractAddressGoeshere>
            },
            currentBlockNumber_hex
        ]
    }

También podría (solo para tener cuidado) hacer una llamada para currentBlockNumber_hex + 1

payload = {
        "id": randint(0, 99999999999999),
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "data": <DataGoesHere>,
                "to": <ContractAddressGoeshere>
            },
            currentBlockNumber_hex + 1
        ]
    }

Y mientras estoy en eso, también puedo hacer currentBlockNumber_hex + 2

payload = {
        "id": randint(0, 99999999999999),
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "data": <DataGoesHere>,
                "to": <ContractAddressGoeshere>
            },
            currentBlockNumber_hex + 2
        ]
    }

Pero esto parece una tontería. ¿Hay una mejor manera? Tengo muchos nodos con fines de redundancia. Y he notado que no siempre están perfectamente de acuerdo con los datos más recientes. Uno o dos pueden retrasarse algunas cuadras por varias razones.

Por ejemplo, puedo hacer una llamada eth_call a los 3 nodos y estos son los resultados:

{
  'node1': {
    'jsonrpc': '2.0',
    'result': '0x14ef054e8f9ef79',
    'id': 38577622847874
  },
  'node2': {
    'jsonrpc': '2.0',
    'result': '0x14ef054e8f9ef79',
    'id': 38577622847874
  },
  'node3': {
    'jsonrpc': '2.0',
    'result': '0x14ef054e8f9ef79',
    'id': 50123622847874
  }
}

Y aquí están los últimos números de bloque:

node1: 6262258
node2: 6262257
node3: 6262259

Observe que el nodo 3 está por delante y casualmente tiene el valor más reciente, mientras que los nodos 1 y 2 están por detrás y aún no tienen el estado más reciente.

Si elijo la Opción 1.) desde arriba, no tengo forma de saber si el resultado del nodo 3 de 0x14ef054e8f9ef79 es en realidad del bloque 6262259 porque se llamó por separado con el parámetro 'más reciente'.

si elijo la Opción 2.) desde arriba, tengo que hacer una cantidad increíble de llamadas solo para verificar que este es el valor más reciente. Estaré haciendo 9 llamadas. Nodo1 en el bloque 6262258, Nodo1 en el bloque (6262258 + 1), Nodo1 en el bloque (6262258 + 2). Luego Node2 en el bloque 6262257, Node2 en el bloque (6262257 + 1), Node2 en el bloque (6262257 + 2). Luego Node3 en el bloque 6262259, Node3 en el bloque (6262259 + 1), Node3 en el bloque (6262259 + 2). Son 9 llamadas solo para obtener un valor. De acuerdo, aumentará la probabilidad de que tenga el último valor absoluto (en comparación con la Opción 1), por lo que puede valer la pena.

Editar: creo que tiene sentido hacer una conexión websocket a cada nodo para escuchar un nuevo número de bloque. Luego vaya con ese número de bloque para la opción 2 y no se moleste con el bloque futuro +1, +2, ya que resultará en muchas llamadas adicionales.

Respuestas (1)

Implementé la Opción 2 de mi publicación anterior y funciona muy bien. Incluso implementé la capacidad de, simultáneamente y en paralelo, consultar números de bloque en el futuro (la cosa actual, actual+1, actual+2). Después de muchas pruebas, determiné que +1, +2 no era necesario después de hacer lo siguiente:

1.) Asigne más recursos a la máquina que ejecuta el nodo, específicamente más memoria. Descubrí que los nodos de paridad con más memoria (mínimo de 8 gb) tienen menos probabilidades de atrasarse unos bloques e incluso menos probabilidades de fallar.
2.) encuesta más agresiva para el último número de bloque.
3.) (todavía probando con este vs 2.) Use la conexión websocket al nodo para obtener los datos más recientes.