Antecedentes, cronología y por qué decidimos construir BOSminer en Rust
Hace poco más de un año, lanzamos nuestro primer proyecto de software de código abierto para la minería de Bitcoin: Braiins OS. La necesidad de un sistema operativo de código abierto para mineros ASIC se hizo evidente con el fiasco encubierto de AsicBoost de 2017 (del que hablamos aquí), pero iba a ser importante independientemente de ese incidente. Con tan pocos fabricantes de HW competitivos construyendo máquinas ASIC para Bitcoin, proporcionar una alternativa transparente al firmware de fábrica aumenta la descentralización en lo que es quizás la parte más centralizada de toda la industria.
Sin embargo, el sistema operativo Braiins es sólo un componente de la pila completa de minería de Bitcoin. Nuestra mayor ambición cuando comenzamos este proyecto era hacer que la pila completa fuera de código abierto, estandarizada, eficiente y segura. Eso significa abordar los otros componentes de la pila: CGminer y el protocolo Stratum. Compartiremos una actualización sobre este último en un futuro post, pero por ahora nos centraremos en la alternativa que hemos desarrollado para sustituir a CGminer, que llamamos BOSminer.
CGminer comenzó como un minero de código abierto para la CPU que cualquiera podía ejecutar. Con la introducción de la minería en la GPU a finales de 2010, empezamos a ver cómo desaparecían algunas de las partes de código abierto del minero. Cada variante de la GPU tenía piezas especiales del núcleo de la GPU que se estaban desarrollando, y sólo una parte de ellas se convirtió en código abierto de inmediato. La comunidad en general se vio obligada a utilizar lo que estuviera disponible.
Las FPGAs fueron la siguiente evolución del hardware minero, pero no cambió mucho en lo que respecta a este componente de CGminer. Algunos hicieron su código abierto, mientras que otros no lo hicieron.
Luego, a finales de 2012, los ASIC entraron en el mercado y rápidamente comenzaron a dominar el SHA-256. Los ASIC son dispositivos integrados, lo que significa que contienen un sistema informático de propósito especial (en lugar de general). La arquitectura típica de un ASIC consiste en lo siguiente:
Normalmente, tienes una placa de control con una FPGA y una CPU que ejecuta algún tipo de Linux en ella, y luego tienes algunas placas de hashing con chips de minería que realizan el trabajo real de minería de Bitcoin. El papel de la placa de control en esta arquitectura es alimentar continuamente los chips con la cantidad adecuada de nuevo trabajo de minería. Originalmente, el CGminer se utilizaba para este propósito. Sin embargo, con el tiempo, los fabricantes cambiaron la lógica de CGminer a las FPGAs en la placa de control.
El ejemplo más conocido de esto es el que mencionamos anteriormente: el incidente de AsicBoost con los Antminer S9 en el que las FPGAs estaban entre la CPU y los hashboards, permitiendo la funcionalidad de AsicBoost de forma encubierta. El fabricante esencialmente impidió el uso de AsicBoost porque el código del controlador era intencionadamente erróneo y no estaba documentado. Había disponible algo de código fuente de CGminer, pero sólo generaba soluciones malas y era prácticamente inútil.
En la actualidad, necesitamos una FPGA y un microcontrolador para manejar las tablas de hashing. El CGminer se ha convertido esencialmente en un front-end desorganizado y muy limitado para las FPGAs. De hecho, llegó a un punto en el que incluso el ingeniero que lo creó, Con Kolivas, tuvo que dejar de darle soporte.
Al mismo tiempo, la arquitectura ASIC es tal ahora que el CGminer por sí mismo no es suficiente para ejecutar todo el sistema porque está ejecutando algo de Linux. Así que se necesitan controladores, cargadores de arranque, etc. para que funcione realmente, que también suelen ser de código cerrado. Incluso cuando los fabricantes dicen que cumplen con la Licencia Pública General (GPL), sigue siendo responsabilidad de los individuos tratar de reunir todas las piezas de software y de alguna manera parchearlas para conseguir una imagen completa del sistema. En pocas palabras, es un lío.
Hay muchos proyectos de código abierto interesantes que se están desarrollando en el ecosistema de Bitcoin en estos días, pero la minería, por desgracia, se ha quedado atrás. Teniendo en cuenta incidentes como las puertas traseras del minero Antbleed y el AsicBoost encubierto, decidimos que ya era hora de hacer algo al respecto. Obviamente es complicado porque hay varios tipos de dispositivos de minería y los diferentes fabricantes a menudo no publican sus modificaciones en el código base de CGminer (violando la GPL).
Por eso empezamos a desarrollar el firmware de Braiins para dispositivos de minería. Y una de las cosas más interesantes es que decidimos escribir nuestro software en el lenguaje de programación Rust, lo que está resultando ser una decisión desafiante pero gratificante.
Al tener una amplia experiencia en el desarrollo de sistemas embebidos, sabíamos que esto iba a suponer un gran reto, independientemente del lenguaje que eligiéramos. Dicho esto, Rust es un lenguaje de programación moderno con un puñado de propiedades que lo hacen ideal para este tipo de aplicaciones:
Rust realiza la mayoría de sus comprobaciones de seguridad y decisiones de gestión de memoria cuando está compilando. Como resultado, está mejor protegido de los errores de software y otras vulnerabilidades de seguridad en relación con los lenguajes no seguros en memoria cuando se trata de acceso a la memoria.
No hay otros lenguajes de programación destacados que estén compilados y fuertemente tipados y que no tengan tiempo de ejecución. Rust no tiene tiempo de ejecución, ni una máquina virtual que maneje la gestión de la memoria - todo se compila estáticamente. Y es mucho más ligero que, por ejemplo, C++. Todo esto lo hace muy adecuado para dispositivos embebidos como los ASIC.
A diferencia de la mayoría de los otros lenguajes, con Rust sabemos que si algo compila para un dispositivo, lo más probable es que el mismo componente de código pueda ser reutilizado en el lado del servidor. Eso es genial, porque permite compartir una misma base de código para los hosts y los dispositivos embebidos, lo que simplifica las pruebas y la producción.
Rust es bastante único en el sentido de que permite utilizar simultáneamente diferentes versiones del mismo paquete de código. En otras palabras, podemos ejecutar dos versiones de la misma biblioteca en una imagen compilada, lo que sería prácticamente imposible si, por ejemplo, utilizáramos C o C++.
En general, a los desarrolladores no les gusta escribir pruebas. Eso se ve con CGminer, donde ninguno de los fabricantes contribuye con casos de prueba. Rust viene con un bonito arnés de pruebas, así que puedes simplemente ejecutar "test" y comprobar que no hay regresiones en el código..
Hay que tener en cuenta que empresas como Microsoft, Amazon y muchas otras están invirtiendo mucho en el desarrollo de Rust. Tiene sentido elegir una tecnología con un futuro brillante por delante. Además, eso significa que debería haber un código más reutilizable, lo que puede ahorrarnos mucho tiempo en el desarrollo futuro.
El primer reto al que nos enfrentamos tras decidir utilizar Rust fue simplemente la escasez de ingenieros que pudieran trabajar con él. Braiins tiene su sede en la República Checa, y sencillamente no hay muchos desarrolladores de Rust por ahí buscando trabajo. (Tomad nota, estudiantes de informática 😉 ). Ciertamente hay un interés creciente en Rust y teníamos varias personas en nuestro equipo que estaban dispuestas a asumir el reto de aprenderlo, pero tardamos muchos meses en llegar al punto en el que éramos lo suficientemente productivos en la base de código como para empezar a generar código original internamente. (Y por cierto, todavía estamos contratación de ingenieros.)
Una vez tomada la decisión de utilizar Rust y de contar con un equipo competente, llegó el momento de empezar a diseñar el software. Esta es la parte divertida, por supuesto, pero viene acompañada de decisiones y retos más difíciles.
Una de las primeras decisiones que tuvimos que tomar fue cómo íbamos a dividir nuestro cálculo en tareas. Hay dos opciones:
Este es un método bien establecido en el que tienes bibliotecas y creas hilos para sincronizarlas. El código base para esto es muy sólido en Rust. Sin embargo, el multithreading no escala si estás recibiendo muchas peticiones en tu red (como es el caso de la minería de Bitcoin), y tener muchos hilos te ralentiza porque es una tarea completa en el SO compartiendo el mismo espacio de direcciones.
El enfoque asíncrono requiere más reflexión previa, pero puede escalar increíblemente bien en un solo hilo. Ya teníamos algunos ingenieros que han trabajado con node.js, y nos resulta más fácil encontrar desarrolladores que piensen en términos de programación asíncrona. El inconveniente de async es que es invasivo para el diseño de tu software: lo contamina todo y se filtra a través de las capas. Así que tienes que ser constantemente consciente de ello mientras diseñas el software.
Al final, vimos que el enfoque asíncrono iba a ser rentable a largo plazo. Sin embargo, en ese momento, el marco de trabajo asíncrono para Rust no estaba donde nos hubiera gustado que estuviera. (Si miras en este sitio webpuedes ver el estado actual de las cosas. Dependiendo de cuándo leas esto, puede que sea realmente asíncrono... pero en el momento de escribir esto todavía faltan un par de cosas. Sin embargo, la biblioteca estándar ha madurado lo suficiente y todas las palabras clave async son estables, por lo que nos sentimos cómodos para tomar el camino async.
Esta fue sólo una de las docenas de decisiones y desafíos a los que nos hemos enfrentado hasta ahora al escribir este software en Rust, pero no podemos abarcarlo todo de forma concisa en este post. Si tienes curiosidad por saber más sobre el proceso de diseño, permanece atento al vídeo de la charla completa de Jan en Dev++ en Tel Aviv. (Debería publicarse a mediados de octubre).
Hemos estado trabajando en dos piezas importantes de la pila de minería de Bitcoin en paralelo, que son BOSminer y Stratum V2. Un buen efecto secundario de esto es que hemos sido capaces de incluir un simulador de Stratum V2 en el prototipo de BOSminer que lanzamos para las pruebas de los desarrolladores. Lo siguiente en la agenda es añadir un proxy V2 (escrito en Rust) también para que podamos simular varios escenarios posibles de despliegue.
Mientras tanto, tomaremos los comentarios de los desarrolladores y mejoraremos BOSminer durante los siguientes meses para lanzar una versión alfa en diciembre, seguida finalmente por un lanzamiento completo alrededor de marzo de 2020. Puedes ver más detalles en la línea de tiempo a continuación.
Una vez que el BOSminer completo sea lanzado, nos facilitará significativamente el añadir soporte para diferentes máquinas ASIC en el futuro, como las últimas Whatsminer M20S y Antminer S17. Teniendo en cuenta esto, actualmente estamos dedicando la mayor parte de nuestros esfuerzos y recursos a hacer que BOSminer sea una realidad en el plazo indicado.
Conferencia | Web | X | Dónde | En | Confirmado |
---|---|---|---|---|---|
Celda | Celda | Celda | Celda | ||
Celda | Celda | Celda | Celda | ||
Celda | Celda | Celda | Celda | ||
Celda | Celda | Celda | Celda | ||
Celda | Celda | Celda | Celda | ||
Celda | Celda | Celda | Celda | ||
Celda | Celda | Celda | Celda |
Empresa de software de minería Bitcoin: Braiins Pool, Braiins OS & Stratum V2.
Por mineros, para mineros.
Aumente el hashrate de sus ASICs de Bitcoin, mejore la eficiencia hasta un 25%, y mine en cualquier pool o obtenga 0% de tarifas de pool en Braiins Pool.
Reduzca la transmisión de datos entre su granja y el pool en un 95%. Configure el uso paralelo de múltiples pools. Configure un pool de respaldo para toda la granja.
Se centra en hacer más eficientes las transferencias de datos, reducir los requisitos de infraestructura física para las operaciones mineras y aumentar la seguridad
Líderes de la industria en transparencia e innovación, con más de 1.25 millones de BTC minados desde 2010
Publicado en
27.9.2019
Antecedentes, cronología y por qué decidimos construir BOSminer en Rust
Índice de contenidos
Hace poco más de un año, lanzamos nuestro primer proyecto de software de código abierto para la minería de Bitcoin: Braiins OS. La necesidad de un sistema operativo de código abierto para mineros ASIC se hizo evidente con el fiasco encubierto de AsicBoost de 2017 (del que hablamos aquí), pero iba a ser importante independientemente de ese incidente. Con tan pocos fabricantes de HW competitivos construyendo máquinas ASIC para Bitcoin, proporcionar una alternativa transparente al firmware de fábrica aumenta la descentralización en lo que es quizás la parte más centralizada de toda la industria.
Sin embargo, el sistema operativo Braiins es sólo un componente de la pila completa de minería de Bitcoin. Nuestra mayor ambición cuando comenzamos este proyecto era hacer que la pila completa fuera de código abierto, estandarizada, eficiente y segura. Eso significa abordar los otros componentes de la pila: CGminer y el protocolo Stratum. Compartiremos una actualización sobre este último en un futuro post, pero por ahora nos centraremos en la alternativa que hemos desarrollado para sustituir a CGminer, que llamamos BOSminer.
CGminer comenzó como un minero de código abierto para la CPU que cualquiera podía ejecutar. Con la introducción de la minería en la GPU a finales de 2010, empezamos a ver cómo desaparecían algunas de las partes de código abierto del minero. Cada variante de la GPU tenía piezas especiales del núcleo de la GPU que se estaban desarrollando, y sólo una parte de ellas se convirtió en código abierto de inmediato. La comunidad en general se vio obligada a utilizar lo que estuviera disponible.
Las FPGAs fueron la siguiente evolución del hardware minero, pero no cambió mucho en lo que respecta a este componente de CGminer. Algunos hicieron su código abierto, mientras que otros no lo hicieron.
Luego, a finales de 2012, los ASIC entraron en el mercado y rápidamente comenzaron a dominar el SHA-256. Los ASIC son dispositivos integrados, lo que significa que contienen un sistema informático de propósito especial (en lugar de general). La arquitectura típica de un ASIC consiste en lo siguiente:
Normalmente, tienes una placa de control con una FPGA y una CPU que ejecuta algún tipo de Linux en ella, y luego tienes algunas placas de hashing con chips de minería que realizan el trabajo real de minería de Bitcoin. El papel de la placa de control en esta arquitectura es alimentar continuamente los chips con la cantidad adecuada de nuevo trabajo de minería. Originalmente, el CGminer se utilizaba para este propósito. Sin embargo, con el tiempo, los fabricantes cambiaron la lógica de CGminer a las FPGAs en la placa de control.
El ejemplo más conocido de esto es el que mencionamos anteriormente: el incidente de AsicBoost con los Antminer S9 en el que las FPGAs estaban entre la CPU y los hashboards, permitiendo la funcionalidad de AsicBoost de forma encubierta. El fabricante esencialmente impidió el uso de AsicBoost porque el código del controlador era intencionadamente erróneo y no estaba documentado. Había disponible algo de código fuente de CGminer, pero sólo generaba soluciones malas y era prácticamente inútil.
En la actualidad, necesitamos una FPGA y un microcontrolador para manejar las tablas de hashing. El CGminer se ha convertido esencialmente en un front-end desorganizado y muy limitado para las FPGAs. De hecho, llegó a un punto en el que incluso el ingeniero que lo creó, Con Kolivas, tuvo que dejar de darle soporte.
Al mismo tiempo, la arquitectura ASIC es tal ahora que el CGminer por sí mismo no es suficiente para ejecutar todo el sistema porque está ejecutando algo de Linux. Así que se necesitan controladores, cargadores de arranque, etc. para que funcione realmente, que también suelen ser de código cerrado. Incluso cuando los fabricantes dicen que cumplen con la Licencia Pública General (GPL), sigue siendo responsabilidad de los individuos tratar de reunir todas las piezas de software y de alguna manera parchearlas para conseguir una imagen completa del sistema. En pocas palabras, es un lío.
Hay muchos proyectos de código abierto interesantes que se están desarrollando en el ecosistema de Bitcoin en estos días, pero la minería, por desgracia, se ha quedado atrás. Teniendo en cuenta incidentes como las puertas traseras del minero Antbleed y el AsicBoost encubierto, decidimos que ya era hora de hacer algo al respecto. Obviamente es complicado porque hay varios tipos de dispositivos de minería y los diferentes fabricantes a menudo no publican sus modificaciones en el código base de CGminer (violando la GPL).
Por eso empezamos a desarrollar el firmware de Braiins para dispositivos de minería. Y una de las cosas más interesantes es que decidimos escribir nuestro software en el lenguaje de programación Rust, lo que está resultando ser una decisión desafiante pero gratificante.
Al tener una amplia experiencia en el desarrollo de sistemas embebidos, sabíamos que esto iba a suponer un gran reto, independientemente del lenguaje que eligiéramos. Dicho esto, Rust es un lenguaje de programación moderno con un puñado de propiedades que lo hacen ideal para este tipo de aplicaciones:
Rust realiza la mayoría de sus comprobaciones de seguridad y decisiones de gestión de memoria cuando está compilando. Como resultado, está mejor protegido de los errores de software y otras vulnerabilidades de seguridad en relación con los lenguajes no seguros en memoria cuando se trata de acceso a la memoria.
No hay otros lenguajes de programación destacados que estén compilados y fuertemente tipados y que no tengan tiempo de ejecución. Rust no tiene tiempo de ejecución, ni una máquina virtual que maneje la gestión de la memoria - todo se compila estáticamente. Y es mucho más ligero que, por ejemplo, C++. Todo esto lo hace muy adecuado para dispositivos embebidos como los ASIC.
A diferencia de la mayoría de los otros lenguajes, con Rust sabemos que si algo compila para un dispositivo, lo más probable es que el mismo componente de código pueda ser reutilizado en el lado del servidor. Eso es genial, porque permite compartir una misma base de código para los hosts y los dispositivos embebidos, lo que simplifica las pruebas y la producción.
Rust es bastante único en el sentido de que permite utilizar simultáneamente diferentes versiones del mismo paquete de código. En otras palabras, podemos ejecutar dos versiones de la misma biblioteca en una imagen compilada, lo que sería prácticamente imposible si, por ejemplo, utilizáramos C o C++.
En general, a los desarrolladores no les gusta escribir pruebas. Eso se ve con CGminer, donde ninguno de los fabricantes contribuye con casos de prueba. Rust viene con un bonito arnés de pruebas, así que puedes simplemente ejecutar "test" y comprobar que no hay regresiones en el código..
Hay que tener en cuenta que empresas como Microsoft, Amazon y muchas otras están invirtiendo mucho en el desarrollo de Rust. Tiene sentido elegir una tecnología con un futuro brillante por delante. Además, eso significa que debería haber un código más reutilizable, lo que puede ahorrarnos mucho tiempo en el desarrollo futuro.
El primer reto al que nos enfrentamos tras decidir utilizar Rust fue simplemente la escasez de ingenieros que pudieran trabajar con él. Braiins tiene su sede en la República Checa, y sencillamente no hay muchos desarrolladores de Rust por ahí buscando trabajo. (Tomad nota, estudiantes de informática 😉 ). Ciertamente hay un interés creciente en Rust y teníamos varias personas en nuestro equipo que estaban dispuestas a asumir el reto de aprenderlo, pero tardamos muchos meses en llegar al punto en el que éramos lo suficientemente productivos en la base de código como para empezar a generar código original internamente. (Y por cierto, todavía estamos contratación de ingenieros.)
Una vez tomada la decisión de utilizar Rust y de contar con un equipo competente, llegó el momento de empezar a diseñar el software. Esta es la parte divertida, por supuesto, pero viene acompañada de decisiones y retos más difíciles.
Una de las primeras decisiones que tuvimos que tomar fue cómo íbamos a dividir nuestro cálculo en tareas. Hay dos opciones:
Este es un método bien establecido en el que tienes bibliotecas y creas hilos para sincronizarlas. El código base para esto es muy sólido en Rust. Sin embargo, el multithreading no escala si estás recibiendo muchas peticiones en tu red (como es el caso de la minería de Bitcoin), y tener muchos hilos te ralentiza porque es una tarea completa en el SO compartiendo el mismo espacio de direcciones.
El enfoque asíncrono requiere más reflexión previa, pero puede escalar increíblemente bien en un solo hilo. Ya teníamos algunos ingenieros que han trabajado con node.js, y nos resulta más fácil encontrar desarrolladores que piensen en términos de programación asíncrona. El inconveniente de async es que es invasivo para el diseño de tu software: lo contamina todo y se filtra a través de las capas. Así que tienes que ser constantemente consciente de ello mientras diseñas el software.
Al final, vimos que el enfoque asíncrono iba a ser rentable a largo plazo. Sin embargo, en ese momento, el marco de trabajo asíncrono para Rust no estaba donde nos hubiera gustado que estuviera. (Si miras en este sitio webpuedes ver el estado actual de las cosas. Dependiendo de cuándo leas esto, puede que sea realmente asíncrono... pero en el momento de escribir esto todavía faltan un par de cosas. Sin embargo, la biblioteca estándar ha madurado lo suficiente y todas las palabras clave async son estables, por lo que nos sentimos cómodos para tomar el camino async.
Esta fue sólo una de las docenas de decisiones y desafíos a los que nos hemos enfrentado hasta ahora al escribir este software en Rust, pero no podemos abarcarlo todo de forma concisa en este post. Si tienes curiosidad por saber más sobre el proceso de diseño, permanece atento al vídeo de la charla completa de Jan en Dev++ en Tel Aviv. (Debería publicarse a mediados de octubre).
Hemos estado trabajando en dos piezas importantes de la pila de minería de Bitcoin en paralelo, que son BOSminer y Stratum V2. Un buen efecto secundario de esto es que hemos sido capaces de incluir un simulador de Stratum V2 en el prototipo de BOSminer que lanzamos para las pruebas de los desarrolladores. Lo siguiente en la agenda es añadir un proxy V2 (escrito en Rust) también para que podamos simular varios escenarios posibles de despliegue.
Mientras tanto, tomaremos los comentarios de los desarrolladores y mejoraremos BOSminer durante los siguientes meses para lanzar una versión alfa en diciembre, seguida finalmente por un lanzamiento completo alrededor de marzo de 2020. Puedes ver más detalles en la línea de tiempo a continuación.
Una vez que el BOSminer completo sea lanzado, nos facilitará significativamente el añadir soporte para diferentes máquinas ASIC en el futuro, como las últimas Whatsminer M20S y Antminer S17. Teniendo en cuenta esto, actualmente estamos dedicando la mayor parte de nuestros esfuerzos y recursos a hacer que BOSminer sea una realidad en el plazo indicado.
Lea la Política de privacidad.