De las novedades que trae la versión 3.0 de Hyperledger Fabric, la implementación de un algoritmo de consenso BFT (Byzantine Fault-Tolerant) en el servicio de Orderer, es la más interesante sin duda.
Hyperledger Fabric es la tecnología blockchain de tipo permisionado que más está creciendo, principalmente en entornos corporativos. Este crecimiento nace gracias a las características que permiten adaptar las soluciones blockchain a las necesidades de las organizaciones. Tanto a nivel de control de acceso al dato, como la capacidad para desarrollar smart contracts en lenguajes como Go o Javascript. Estos lenguajes son ampliamente utilizados en las compañías y esto ha reducido el tiempo de aprendizaje de los equipos de desarrollo para implementar procesos distribuidos utilizando esta tecnología Blockchain.
Pero Fabric, desde las primeras versiones, ha recibido muchas críticas sobre los métodos y protocolos de consenso que se han implementado, por no ser totalmente descentralizados o incorporar consensos BFT. La razón principal y objeto de las críticas recibidas por Hyperledger Fabric, es que siempre se ha premiado aquellas características, que potenciaban las funcionalidades orientadas a la implementación de los procesos propios de las organizaciones. De todos los componentes de Hyperledger Fabric, el servicio de Ordering es el que ha recibido mayor número de ataques, por ser un elemento que evitaban la total descentralización de la infraestructura Hyperledger Fabric.
¿Qué es el servicio de Ordering?
En Hyperledger Fabric, la responsabilidad de la generación de un bloque está en manos del servicio de Ordering, el cuál se encarga de recibir todas las transacciones y generar el bloque que formará parte de la Blockchain. Pero para entender por qué en Hyperledger Fabric se optó por implementar un servicio para la generación de los bloques, hay que entender cómo es el proceso de construcción de una transacción en Hyperledger Fabric.
El siguiente esquema muestra el flujo de cuatro fases de una transacción.
- El cliente envía a los tres peers encargados de la fase de Endorsement, en la que ejecutan el chaincode y construyen la respuesta de endorsement.
- Los tres peers devuelve al cliente la respuesta que cada uno ha construido.
- El cliente recibe las respuestas de endorsement y construye con ellas una transacción, que envía al servicio de ordering.
- El servicio de ordering recibe las transacciones de distintos clientes y construye un bloque, el cuál se envía a todos los peers que pertenezcan al canal, que validan el bloque y lo incorporan a la blockchain.
Como se puede ver en el esquema anterior, hay dos partes claramente diferenciadas:
- Una parte que consiste en construir una transacción, en la que intervienen el cliente y los peers que ejecutan los smart contracts.
- Otra parte para la construcción del bloque, de la que se encargan los nodos del servicio de ordering.
Pero centrémonos en el servicio de ordering, se trata de un conjunto de nodos los cuales garantiza la recepción de transacciones, la construcción de los bloques y la diseminación de los mismos, entre los distintos canales de la infraestructura Hyperledger Fabric. La historia del servicio de ordering no ha sido fácil en Fabric, de hecho es el componente que más cambios ha tenido a lo largo de estos años y el que más críticas ha recibido.
Aunque desde el principio se ha intentado implementar un consenso basado en BFT, la realidad es que Hyperledger Fabric ha optado por implementar en el servicio de ordering distintas tecnologías como Kafka o RAFT, que son en realidad Crash Fault Tolerant. Los críticos con Hyperledger Fabric, siempre han argumentado que no implementaban un protocolo de consenso BFT, lo que no ha impedido desarrollar un gran número de soluciones.
¿Qué es BFT?
Se denominan protocolos de consenso BFT (Byzantine Fault-Tolerant), a aquellos protocolos que implementan una forma de solucionar el problema de los generales bizantinos. Este problema se planteó para evaluar cómo un sistema distribuido, puede construir una respuesta conjunta y confiable, independientemente de la confianza que se tenga en cada uno de los nodos del sistema.
El problema propone la siguiente situación. Varios ejércitos están rodeando una ciudad. Los distintos generales que comandan cada ejército, deben ponerse de acuerdo para atacar la ciudad a la vez, ya que si no atacan todos juntos, la probabilidad de éxito será muy baja. Por tanto, todos los generales deben ejecutar la misma orden a la vez, para que el ataque a la fortaleza enemiga tenga éxito. O por el contrario, si deciden retirarse, lo deben hacer todos al mismo tiempo, para que el enemigo no aproveche la situación de desventaja en la que quedaría el ejército que no decide retirarse. Un factor importante en este problema, es que los generales no pueden confiar, ni en los mensajeros que se encargan de comunicar las órdenes, ya que estos pueden ser eliminados o interceptados para alterar el mensaje, ni tampoco pueden confiar de manera ciega en los otros generales, ya que puede haber algún traidor.
Por tanto, implementar un protocolo de consenso BFT, significa que la decisión que tome el sistema, esté consensuada por la mayoría de los nodos, independientemente de si existen algunos nodos que o bien no participen del proceso de decisión porque están inoperativos, o por que estén comprometidos y el mensaje que emiten, en el proceso de consenso es erróneo o malicioso.
En el paper de Bitcoin, Satoshi propuso un algoritmo de consenso que cumplía con BFT, se trataba de basar el consenso en Prueba de Trabajo (Proof of Work). Con el que se garantizaba que el bloque sería generado por el nodo que consiguiera encontrar un HASH con una estructura determinada, para la que había que comprometer cierta cantidad de recursos, en concreto uso de CPU del nodo. El bloque generado sería validado por el resto de nodos, para evitar que el ganador pudiera meter información maliciosa. Una vez que el bloque ha sido validado formará parte de la blockchain.
El problema principal de este tipo de protocolos de consenso, es que todos los nodos están trabajando a la vez, durante un periodo de tiempo, compitiendo para conseguir ser los primeros en generar un bloque. Hay dos inconvenientes, el tiempo que se debe dedicar al proceso y la cantidad de CPU que se ha utilizado.
¿Por qué Hyperledger Fabric no ha implementado BFT?
Muchas veces la comunidad Blockchain ha lanzado esta pregunta, para entender las razones por las que Fabric no ha implementado un algoritmo de consenso que cumpla con BFT. La razón principal es que Fabric se ha centrado en dos aspectos principalmente:
- Ser una tecnología permisionada, lo que permite generar esquemas de confianza centrados en los participantes.
- Se ha primado el rendimiento y cubrir las necesidades que los entornos corporativos tenían a la hora de abordar la incorporación de la tecnología Blockchain a sus procesos.
Aunque hubo una implementación BFT en la versión 1.0 de Fabric, está fue rápidamente desestimada, porque no estaba completamente integrada en la arquitectura y suponía un punto de fallo a la misma. La estrategia de Fabric a la hora de implementar el proceso de generación de bloques, ha sido desplegar modelos crash fault tolerant (CFT), como Kafka primero y posteriormente Raft. Este tipo de soluciones son tolerantes a fallos, en cuanto que consiste en una serie de nodos, los cuales se encargan de recibir datos (transacciones) y uno de estos nodos, el que tenga en ese momento el rol de líder, construye el nuevo bloque.
Aunque Fabric, para el servicio de ordering, implementa un modelo CFT, esto no significa que sea un tecnología con brechas que reduzca la confianza de la solución. La razón principal, es que el rol que juega el servicio de ordering es el de la construcción del bloque, pero no participa en ninguna de las fases de construcción de la Transacción. Esta separación de funciones, en distintos componentes de la infraestructura, ayuda a garantizar la seguridad de datos que transporta la Transacción. El principal problema del servicio de ordering, no está en que pueda llegar a manipular las transacciones, cosa que no puede hacer, ya que todas las partes de una transacción van firmadas digitalmente por el componente encargado, si no en la disponibilidad del servicio. Ya que una infraestructura Fabric que cuente con un mal diseño en el servicio de Ordering, frente a un ataque, puede dejar a la plataforma fuera de servicio, aunque no se comprometa la confianza de los datos.
BFT en Fabric v3.0
La nueva versión de Fabric, incorpora un servicio de ordering que implementa un algoritmo de consenso basado en BFT, concretamente en SmartBFT, cuya definición está en paper “A Byzantine Fault-Tolerant Consensus Library for Hyperledger Fabric, escrito por Artem Barger, Yacov Manevich, Hagar Meir, Yoav Tock. La siguiente figura muestra un esquema de la arquitectura implementada, con la relación entre los distintos componentes.
El protocolo es el siguiente:
- El cliente construye la Tx con las respuesta obtenida durante la fase de endorsement, exactamente igual a como se hace actualmente con Raft.
- El cliente envía la Tx a TODOS los nodos del servicio de Ordering. Esto es importante, ya que antes el cliente no tenía que hacer esto.
- El nodo Orderer, filtra la Tx en función de las reglas que se hayan codificado en el componente VALIDATOR,
- Si la Tx es válida se pasa a CONSENSUS LIBRARY. Las Tx se encolan en un pool.
- El nodo líder del servicio de ordering agrupará las transacciones entrantes y luego llamará al ASSEMBLER, para ensamblar estas transacciones en un bloque. El ensamblador es responsable de garantizar la composición del bloque.
- El nodo líder propondrá entonces el bloque, iniciando el protocolo de consenso.
- Los SEGUIDORES (todos aquellos nodos que no son el líder en este momento) recibirán la propuesta de bloque y validarán cada transacción utilizando el mismo VALIDATOR que ha utilizado el líder.
- Cada uno de los nodos firma el mensaje de confirmación de bloque válido y lo envía al resto de nodos.
- Cuando se acumulan suficientes mensajes de confirmación válidos, el bloque junto con todas las firmas de confirmación, se entrega al componente de confirmación COMMITTER que lo guarda en el almacén de bloques.
- Cuando el Peer obtiene el bloque debe validarlo. Cada bloque que recibe pasa por un componente de validación de bloque que garantiza que esté firmado correctamente por un número de nodos de tipo Orderer suficiente, como lo requiere el protocolo BFT.
Aunque siempre son buenas noticias ver cómo Hyperledger Fabric va incorporando mejoras como ésta, la realidad es que el cambio no se demasiado grande, ya que como hemos comentado en el post, actualmente puedes construir soluciones lo suficientemente confiables y distribuidas, para considerar Fabric como una de las mejores opciones a la hora de afrontar un proyecto para implementar un proceso distribuido, seguro y confiable.
José Juan Mora Pérez
CTO & Founder