¿Cómo hacen los operadores de pools su hashing?

Para cada "getwork" servido por el grupo, se debe calcular una raíz de Merkle para un bloque. El tiempo de ejecución de SHA-256 es proporcional a la cantidad de "fragmentos" de 256 bits, y un bloque típico tendrá miles de estos fragmentos (un encabezado de bloque solo tiene tres, después del preprocesamiento). Por lo tanto, el operador del grupo necesitará una potencia de hash en el rango de Mhash/seg, aproximadamente. ¿Tengo razón hasta ahora?

Los mineros individuales necesitan mucho más poder de hash, pero de una forma más simple: aquí hay un encabezado de bloque preprocesado de tres partes; hash con cada uno de 0000_0000x a FFFF_FFFFx en el campo nonce. Si los motores hash se especializan en esa simplicidad, para hacerlos más baratos y/o más rápidos, entonces no funcionan tan bien para los operadores de pools.

Entonces, si soy un operador de grupo o un minero independiente y necesito generar millones de raíces de Merkle, ¿cuáles son mis opciones? ¿Los motores hash (CPU/GPU/FPGA/ASIC) tienen una API que pueda usar?

Relacionado: Getwork es solo un enfoque para distribuir el trabajo para la minería en grupo.

Respuestas (2)

Un grupo generalmente creará una raíz merkle única para cada solicitud de trabajo de un minero. Si acepta acciones de dificultad 1, el minero puede gastar un promedio de aproximadamente 4000 Mega-hashes en ese bloque (y ganará un promedio de 1 acción por getwork).

Para crear un encabezado de bloque para cada minero, el operador del grupo cambia cierta información única en la primera transacción (generación) del bloque y luego vuelve a procesar el bloque para crear la raíz merkle. Si se hace de manera ingenua, esto tomará hashes O(N log N) sha256 (donde N es el número de transacciones en el bloque que se está extrayendo). Al guardar parte de la información del cálculo de la última raíz Merkle, puede volver a calcular un cambio en la transacción de generación con solo hashes O (log N).

Con cientos de transacciones por bloque, la proporción de hashes realizados por el operador del grupo y los mineros supera los 100 millones a 1.

Para un ahorro aún mayor, los grupos pueden aceptar una solicitud de API getblocktemplate en lugar de una solicitud de getwork. Este modo le permite al minero generar sus propios encabezados de bloque y minar durante un promedio de 10 minutos antes de que el grupo deba actualizarlos.

Una parte del trabajo del servidor que requiere mucha computación es la creación de nuevas raíces Merkle. Como menciona mckoss, esto se vuelve mucho más rápido si solo vuelve a calcular la rama de merkle que cambia con la transacción de nueva generación en lugar de volver a calcular todo el árbol de merkle.

La otra parte del trabajo del servidor que requiere mucha computación es verificar las pruebas de trabajo que se envían más tarde. En general, esto significa dividir dos fragmentos SHA-256 y verificar el resultado contra la dificultad. Pero si hay varias pruebas de trabajo con la misma raíz de merkle, entonces podría calcular el estado medio una vez y luego solo codificar un fragmento SHA-256 para cada prueba de trabajo que desee verificar. Tal como lo hacen los clientes con rollntime.

Por lo tanto, cada nueva raíz de merkle es trabajo para generar, y también crea más trabajo más tarde al necesitar calcular un nuevo estado medio.

BitMinter hace uso de rodar el campo ntime tanto en el servidor como en el cliente. Cada vez que el reloj de pared avanza un segundo, actualiza el campo ntime de los datos del bloque con una nueva marca de tiempo. Luego, puede reutilizar todas las raíces y estados medios de Merkle que tiene del segundo anterior.

Esto ahorra una gran cantidad de trabajo en el servidor, y así es como BitMinter podría ejecutarse con poca carga en un solo servidor con 2-3 TH/s de potencia de hash, mientras que algunos grupos (no bien optimizados) necesitaban un nuevo servidor por cada 300 GH. /s de potencia hash.

Desde entonces, tales optimizaciones se han vuelto menos importantes. Más clientes comenzaron a admitir rollntime. Los servidores y los clientes comenzaron a usar una dificultad de trabajo superior a 1, lo que significa que se tuvo que verificar mucho menos trabajo en el servidor. Y luego están los nuevos protocolos para reemplazar getwork: Stratum y GBT (getblocktemplate). Con estos protocolos, el servidor solo genera una plantilla que es muy económica de generar, luego los clientes hacen la parte más pesada de crear el trabajo basado en la plantilla.

Sigo pensando que es una buena idea que los clientes usen el truco ntime para reutilizar las raíces y estados intermedios de Merkle, lo que también permite la reutilización de estados intermedios en el lado del servidor, aunque esto ya no es gran cosa.