Polkadot v1.0: Sharding y Seguridad Económica
20 de enero de 2022 en Polkadot.
Por Rob Habermeier, Fundador de Polkadot. Traducción de Lorena Fabris
Este post trata sobre la tecnología que impulsa Polkadot. Polkadot es una blockchain fragmentada (sharded blockchain) con fragmentos (shards) heterogéneos. Lo que significa sharding en este contexto es la división del trabajo que ocurre en múltiples sub-blockchains, conocidas como parachains. Lo que significa heterogéneo en este contexto es que cada blockchain tiene su propia función de transición de estado (state transition) que está diseñada para un caso de uso específico. Diferentes tipos de transacciones tendrán diferentes homes, lo que permite que las cadenas especializadas sirvan a sus usuarios de manera más eficiente. Polkadot proporciona seguridad y funcionalidad de mensajería para todas las parachains adjuntas.
Este post está escrito principalmente para un público técnico con algunos conocimientos sobre el consenso de la blockchain. Espero que sea útil para las personas más allá de esa audiencia y que proporcione una visión de los problemas y desafíos a los que se enfrentan las blockchains de la capa base y cómo Polkadot aborda estos problemas. No voy a repasar todos los matices de nuestras soluciones, pero sí daré una descripción profunda de los tipos de cosas que tenemos en cuenta y cómo proporcionamos las garantías que pretendemos.
Las cadenas antes de la cadena
Una comprensión simplificada de la blockchain implica una sola cadena, que se extiende desde la génesis hasta el encabezado de la cadena. Para mucha gente, éste es el único concepto de la cadena que importa: representa todas las transiciones de estado que han ocurrido y han sido acordadas por la red. El objetivo final de cualquier sistema de consenso de blockchain es proporcionar a los observadores esta fuente de verdad. Sin embargo, esta única cadena, a la que podemos referirnos como la cadena finalizada o canónica, es sólo la última sobreviviente de las muchas cadenas posibles que podrían haber existido. El rol del algoritmo de consenso de la blockchain es comenzar con muchas cadenas posibles y finalmente finalizar sólo una de ellas.
Los autores de los bloques compiten por el derecho a producir el siguiente bloque, pero puede haber más de un ganador a la vez. En la prueba de trabajo (proof of work), los mineros se ganan el derecho de autor sobre un bloque dado (aproximadamente) encontrando una manera de producir un nuevo bloque cuyo hash sea un número aleatorio único que caiga por debajo de algún objetivo difícil. Puede hacer falta un gran número de intentos antes de que un minero encuentre un bloque que satisfaga esta condición en un entorno suficientemente competitivo. Como referencia, el hashrate acumulado de la red Bitcoin en el momento de escribir este artículo es de 162 Exahashes por segundo, lo que significa que los mineros de Bitcoin en conjunto intentan 162 quintillones de veces por segundo para ganarse el derecho a contribuir al siguiente bloque, y el objetivo de dificultad se establece de manera que, en promedio, sólo un hash estará por debajo del objetivo cada 10 minutos. Hay que tener en cuenta que es posible que varios mineros encuentren, más o menos simultáneamente, una solución, lo que introduce una pequeña bifurcación en la blockchain. Los futuros mineros tendrán que elegir sobre cuál de esos bloques minar, lo que puede hacer que las bifurcaciones se alarguen. La regla es seguir la cadena más larga, y se vuelve progresivamente más difícil para un atacante que comienza desde un bloque pasado alcanzar y sobrecargar a alguna cadena más larga. Por ello, un bloque que esté lo suficientemente profundo en la cadena más larga puede considerarse probabilísticamente definitivo.
La familia Ouroboros de protocolos de proof of stake (prueba de participación) utiliza la tecnología criptográfica conocida como Verifiable Random Functions [Funciones Aleatorias Verificables (VRFs)] para simular la proof of work (prueba de trabajo) dividiendo el tiempo en slots (ranuras) diferenciados y dando a cada validador de un conjunto de validadores registrado y con staking [validator set (conjunto de validadores)] la oportunidad de producir un valor aleatorio verificable por slot de tiempo (time-slot), que, si está por debajo de un umbral, sirve como credencial para permitir al validador ser el autor de un nuevo bloque. Al igual que con proof of work, varios validadores pueden producir un valor con sus VRFs que caiga por debajo del umbral y simultáneamente crear bloques, lo que lleva a bifurcaciones. Se desincentiva a los validadores para que no introduzcan bifurcaciones intencionadas, es decir, que utilicen su credencial para crear varios bloques en el mismo slot, reduciendo (slashing) su stake (participación) en la cadena. Estos protocolos también proporcionan una finalidad probabilística bajo la regla de elección de la bifurcación de la cadena mas larga.
A diferencia de los mineros en proof of work, los validadores en una red de estilo Ouroboros sólo necesitan realizar un cálculo para tener la oportunidad de crear un bloque, en lugar del número absurdamente grande de hashes que tienen que hacer los mineros. Esto permite a los validadores dedicar la mayor parte de su tiempo a la construcción de un bloque con transacciones y, por consiguiente, permite que la blockchain contenga cálculos más valiosos.
La relay chain de Polkadot utiliza un protocolo llamado BABE, que es una evolución de Ouroboros Praos. La mejora específica que BABE tiene sobre Praos es que BABE evita depender de servidores NTP centralizados para que los validadores conozcan el tiempo actual.
Aunque la finalidad probabilística está bien, esperar a que un bloque alcance una determinada profundidad en la cadena más larga es un mecanismo ineficiente, ya que está diseñado para acomodar un peor caso anticipado en el que la red está bajo un cierto nivel de tensión y ataque de la red. Puede darse el caso de que la mayoría de la red ya esté de acuerdo en qué bloques forman parte de la cadena canónica. De hecho, en casi todos los casos, la red podrá ponerse de acuerdo en que un bloque sea canónico mucho antes de que alcance la profundidad mínima en la cadena más larga. Para ello, introducimos los conceptos de gadget de finalidad (finality gadget) y de finalidad absoluta (absolute finality). Un gadget de finalidad es un protocolo de consenso secundario que se ejecuta sobre una blockchain probabilísticamente definitiva que demuestra un acuerdo más rápido sobre los bloques que la red considerará definitivos. Estos protocolos de consenso introducen una propiedad de seguridad económica adicional: el gadget de finalidad nunca finalizará 2 bloques que compitan entre sí sin cortar (slashing) al menos 1/3+ del staking total del validator set.
La relay chain de Polkadot utiliza un gadget de finalidad conocido como GRANDPA. Puede lograr una finalidad casi instantánea en subcadenas de cualquier longitud particular, y funciona aproximadamente haciendo que los validadores voten repetidamente los bloques que perciben como el encabezado de la cadena más larga. GRANDPA funciona actualmente en las redes Polkadot y Kusama, y en Kusama, que cuenta con 900 validadores en el momento de escribir este artículo, puede lograr la finalidad de los nuevos bloques en 3 segundos.
Publicación del blog explicativo de GRANDPA
La combinación de BABE y GRANDPA permite a Polkadot un crecimiento optimista de la cadena con la entrada de un solo validador, lo cual es rápido, y finalizarla en segundo plano obteniendo la aprobación de una supermayoría de validadores. Esta combinación de propiedades significa que, en buenas condiciones de la red, Polkadot consigue un alto rendimiento y una baja latencia, y en malas condiciones de la red, la relay chain consigue un alto rendimiento y una alta(o mas alta) latencia, ya que GRANDPA pasará a seguir la finalidad probabilística de BABE.
Sharding: escalada por selección de subconjuntos
Volvamos al sharding (la fragmentación). El objetivo del sharding es mejorar el rendimiento dividiendo el trabajo, en forma de transacciones, en muchas cadenas conocidas como shards (fragmentos). Las shards (fragmentos) están referenciadas y aseguradas por una blockchain de nivel superior. En Polkadot, la blockchain de nivel superior se llama relay chain y las shards son parachains. La mayoría de los datos que aparecen en la relay chain son transacciones que incluyen referencias a nuevos bloques de parachain, lo que hace que el procesamiento de cualquier fork (bifurcación) de la propia relay chain sea barato. Hay que tener en cuenta que aquí hago una distinción entre bifurcaciones arbitrarias de la relay chain y la relay chain finalizada. La mayor parte de nuestro trabajo aquí consiste en asegurar que la parte finalizada de la relay chain, que los usuarios verán como la cadena canónica, sólo contenga referencias a bloques de parachain que sean válidos.
Este diagrama u otros similares se distribuyen ampliamente por Internet. Muestran cómo los validadores se dividen en grupos y se asignan a parachains y obtienen propuestas de bloques de parachain de los collators (recopiladores). En este post he creado explicaciones visuales de muchos de los conceptos más matizados.
El sharding (fragmentación) sólo es una mejora de la escalabilidad si cada validador sólo necesita comprobar algunos de los bloques de parachain enviados, en lugar de todos ellos. Si hubiera 10 parachains, y cada validador tuviera que comprobar todos los bloques de las 10 cadenas, también podríamos poner todas las transacciones en una sola blockchain y dar por terminado el proceso. El truco está en encontrar una manera de que cada validador haga el menor trabajo de verificación posible y al mismo tiempo mantenga la seguridad económica: que los validadores que defienden bloques de parachain malos sean desincentivados económicamente para hacerlo. Más concretamente, debería ser imposible para un grupo adversario de validadores confabularse para conseguir que un bloque de parachain malo se incluya en la relay chain finalizada antes de perder todo su stake (participación) en el slashing. Los validadores, y de hecho pequeños subconjuntos de validadores, pueden confabularse para conseguir bloques de parachain malos referenciados por bifurcaciones no finalizadas de la relay chain, pero nosotros garantizamos que estas bifurcaciones sean ignoradas antes de la finalización y los infractores sean recortados (slashed).
Los bloques de parachain se finalizan cuando se finaliza un bloque de la relay chain que hace referencia a ellos
Establezcamos algunas suposiciones concretas sobre el adversario del que nos defendemos:
- El adversario puede controlar hasta 1/3 de todos los validadores, y puede controlar todos estos validadores para que se comporten exactamente como desea.
- El adversario puede ver todos los mensajes de la red entre los validadores honestos y los validadores que controla
- El adversario puede hacer DoS hasta el X% de los validadores en cualquier momento, impidiéndoles enviar o recibir mensajes.
- Se necesita un retraso fijo antes de que el adversario pueda empezar a hacer DoS a cualquier validador
No voy a establecer una prueba de seguridad formal para el protocolo en este post, pero estas restricciones deberían proporcionar una visión de los tipos de ataques de los que pretendemos defendernos.
De hecho, nuestra unidad base de consenso de parachain no es realmente una parachain, sino algo que llamamos availability core (núcleo de disponibilidad) o core (núcleo) para abreviar. Son algo así como los núcleos de la CPU: funcionan en paralelo y tienen trabajo programado en ellos en discrete time-slot (tiempo de slots diferenciado). Cada parachain tiene su propio núcleo dedicado, lo que significa que siempre está programado en un núcleo concreto. Sin embargo, también podemos multiplexar varias cadenas en un solo núcleo. La única diferencia es el algoritmo de programación.
Los núcleos sirven como descripción efectiva del rendimiento de la relay chain. Los núcleos se corresponden directamente con la cantidad de trabajo que deben realizar los validadores. Cada núcleo puede manejar hasta un bloque de parachain por cada bloque de la relay chain, en el pico.
En cualquier sistema de sharded (fragmentado) blockchain, en el que sólo algunos validadores comprueban cada bloque de parachain, la data availability (disponibilidad de los datos) es un componente crucial para garantizar que los datos necesarios para comprobar un bloque de parachain puedan recuperarse a efectos de detección de fraudes. Los núcleos de disponibilidad son gestionados por la relay chain y hacen un seguimiento de los bloques de parachain que están pendientes de disponibilidad de datos. El objetivo principal de los núcleos de disponibilidad es servir de primitiva de programación y proporcionar presión de retorno cuando la disponibilidad de los datos es más lenta de lo habitual.
La lógica de un núcleo de disponibilidad es la siguiente. Los núcleos están vacíos cuando están preparados para aceptar un nuevo bloque de parachain, momento en el que pasan a estar ocupados. A continuación, los datos pasan a estar disponibles o el proceso de disponibilidad se agota. En ese momento, el núcleo vuelve a estar vacío.
Es útil dividir el consenso de parachain en 5 protocolos distintos que se entrelazan en el consenso de la relay chain.
1. Collation (Compilación)
2. Backing (Respaldo)
3. Availability (Disponibilidad)
4. Approval Checking (Comprobación de la Aprobación)
5. Disputes (Disputas)
Collation La compilación es el proceso por el que se crean los bloques de parachain. Los collators construyen un bloque de parachain y lo envían a los validadores.
Backing El respaldo es el proceso por el cual los bloques de parachain son comprobados inicialmente por un pequeño grupo de validadores de la relay chain y registrados en la relay chain. El principal subproducto del respaldo es que requiere que los validadores se pongan en riesgo si los protocolos posteriores fallan.
Availability La disponibilidad es el proceso por el cual los validadores de respaldo distribuyen piezas de los datos necesarios para comprobar el bloque de parachain y se aseguran de que esté disponible para su comprobación posterior.
Approval Checking La comprobación de la aprobación es el proceso por el cual los validadores aleatorios recuperan los datos y ejecutan el bloque de parachain. Aprueban o inician una disputa en función de si creen que el bloque de parachain es válido.
Disputes Las disputas son el proceso mediante el cual se resuelven las opiniones contradictorias de los validadores sobre un bloque de parachain y se ignoran los bloques de parachain malos y se castiga a los infractores. Las disputas sólo existen como medida de seguridad y no se espera que se activen con frecuencia.
Hay que tener en cuenta que es probable que los validadores participen en cada uno de estos protocolos al mismo tiempo, y a menudo en múltiples instancias de ellos. Por ejemplo, un validador puede estar participando en la votación de aprobación de un bloque de parachain que está más adelante en el pipeline al mismo tiempo que participa en el respaldo de un bloque más nuevo y en las disputas de un bloque aún más antiguo.
Este paralelismo interno también refleja la arquitectura de la implementación: cada uno de estos protocolos se implementa como un subsistema independiente, y todos los subsistemas se ejecutan en paralelo. Cada nodo está siempre haciendo un poco de todo.
Envío de bloques y crecimiento de parachains
Esta sección repasa cómo las parachains crecen junto con la relay chain.
La inclusión de un bloque potencial de parachain en una parachain tiene dos pasos. El primero es que el bloque de la parachain sea referenciado por un bloque de la relay chain junto con los certificados sobre su validez. El siguiente paso es que los datos correspondientes necesarios para comprobar el bloque de parachain sean reconocidos como disponibles en un bloque de relay chain posterior.
Como la relay chain puede tener bifurcaciones a corto plazo, cada parachain también puede tener bifurcaciones a corto plazo. Si hay dos bloques de relay chain A y B que compiten en una altura determinada y A contiene el bloque de parachain P y B contiene el bloque de parachain P’, entonces eso también constituye una bifurcación en la parachain.
Para el propósito de este post, consideraremos una versión simplificada de la máquina de estado de la relay chain de Polkadot. Como recordatorio, cada bloque en una rama de la relay chain representa una transición del estado anterior al siguiente.
Cada bloque significa una unidad atómica de cambio del estado anterior de la blockchain a un nuevo estado. Los saldos de las cuentas, los núcleos de disponibilidad, las propuestas de gobernanza y los contratos inteligentes son todos ejemplos de cosas que forman parte del estado de una blockchain. Los bloques actualizan el estado a través de la lógica inherente o de las transacciones. La lógica inherente se refiere a las actualizaciones de estado que deben ocurrir incluso sin transacciones, como resultado del paso del tiempo o del avance del número de bloques.
Cuando se construye una blockchain, el patrón de diseño típico es que los nodos recopilen información y realicen trabajos fuera de la cadena (off chain) y luego coloquen un registro del trabajo en la cadena (on chain). Como ejemplo, puedes ver la inclusión de transacciones a través de la misma lente. Los nodos participan en un protocolo de gossip (chisme) fuera de la cadena para recopilar nuevas transacciones y, a continuación, el autor del bloque agrupa su elección de transacciones en un bloque. Las parachains funcionan de la misma manera: la mayor parte del trabajo se realiza fuera de la cadena, pero los registros del trabajo se conservan en la relay chain para proporcionar una indicación canónica del consenso.
El trabajo fuera de la cadena que realizan los nodos para hacer crecer las parachains implica collation, backing y availability.
Los nodos supervisan los últimos bloques de la relay chain para determinar qué trabajo deben realizar.
Un collation consiste en un encabezado de parachain y un PoV o proof of validity (prueba de validez) que son todos los datos necesarios para comprobar la transición desde el encabezado de parachain anterior al encabezado actual. Sólo los encabezados se abren paso en la cadena, pero los PoVs deben estar disponibles. Utilizamos erasure coding (codificación de borrado) para garantizar que los PoVs estén disponibles: los datos se dividen en piezas llamadas chunks, una para cada validador, y cualquier subconjunto de chunks lo suficientemente grande puede recuperar los datos completos. Esto proporciona protección contra los nodos que se desconectan o mienten sobre su parte de los datos.
Cuando un validador observa que un núcleo de disponibilidad está vacío y la parachain programada en ese núcleo es una a la que el nodo está asignada, intentará recoger un collation de un collator (colector) y participar en el proceso de backing. Los nuevos bloques de parachain potenciales, junto con sus atestaciones por parte de los validadores, se propagan a través de un sistema de gossip (chisme). Esto significa que todos los nodos bien conectados están al tanto de cada bloque potencial de parachain. El siguiente autor del bloque de la relay chain supervisa el estado de la red y selecciona un conjunto de nuevos bloques de parachain para respaldarlos en el bloque de la relay chain del que es autor.
Este es un diagrama de flujo que describe vagamente la lógica que los validadores realizan para el proceso de backing. Realizan esta lógica siempre que el núcleo de disponibilidad de la parachain esté vacío.
Este diagrama muestra cómo los validadores obtienen bloques de parachain frescos de los collators y colaboran con otros validadores para obtener suficiente apoyo de los validadores asignados. Los validadores que no están asignados a la parachain siguen escuchando las atestaciones porque el validador que acabe siendo el autor del bloque de la relay chain necesita agrupar los bloques de la parachain certificados para varias parachains y colocarlos en el bloque de la relay chain.
Una vez que un bloque de parachain está backed (respaldado) en la cadena (es decir, su encabezado ha aparecido en un bloque de relay chain junto con las atestaciones de los validadores seleccionados y ha pasado varias comprobaciones de cordura) comienza a ocupar el núcleo de disponibilidad.
Cuando un validador observa que un núcleo de disponibilidad está ocupado, intenta obtener su chunk del PoV erasure coded si no formaba parte del grupo de validadores que inicialmente certificaron el bloque. En caso contrario, el validador es responsable de distribuir los chunks a los validadores correspondientes.
Availability distribution (Distribución de la disponibilidad): los validadores que no respaldan el bloque (no backing validators) solicitan sus chunks a los validadores que lo respaldan. Es posible que algunos de los no backing validators no puedan conectarse directamente, pero es es correcto mientras haya suficientes.
Cada validador firma declaraciones sobre los bloques de parachain para los que tiene sus chunks y chismea (gossips) esas declaraciones. El autor del bloque de la relay chain incluye esas declaraciones en la relay chain. Una vez que 2/3+ de los validadores han indicado que tienen su chunk para el bloque de parachain que ocupa un núcleo, el bloque de parachain se considera disponible y se incluye oficialmente como parte de la parachain y el núcleo vuelve a estar libre.
Si no se consigue la disponibilidad dentro de una cantidad determinada de bloques, el núcleo se libera, considerándose que se ha agotado el tiempo (timed out) y el bloque de parachain que ocupa el núcleo se abandona.
En resumen, los protocolos de backing (respaldo) y availability (disponibilidad) garantizan que, en el tiempo en que se ha incluido un bloque de parachain, éste ha sido certificado por un pequeño grupo de validadores y la disponibilidad del PoV necesario para comprobar el bloque de parachain ha sido atestiguada por al menos 2/3 de los validadores. Dicho de otro modo, el backing y la availability tienen que ver con la implicación en el juego y la imposición de responsabilidades. En las siguientes secciones se analizará cómo Polkadot se asegura de que ningún bloque de parachain sea finalizado sin ser comprobado más a fondo.
Comprobación de aprobación y finalidad
Approval Checking (comprobación de aprobación) es un mecanismo por el cual los validadores se auto-seleccionan aleatoriamente para comprobar los bloques de parachain que están disponibles y comunican la intención y los resultados de sus comprobaciones al resto de la red.
Por ahora, vamos a dejar el proceso real de comprobación de aprobación como una caja negra. Empezaremos dando algunos antecedentes sobre lo que queremos que haga este protocolo, para que quede claro más adelante por qué funciona de la manera en que lo hace.
Como ya hemos establecido, cada nodo validador participa en GRANDPA, el gadget de finalidad. GRANDPA procede en rondas, y podemos ver una versión sobre-simplificada del trabajo que cada validador hace en cada ronda de GRANDPA como la repetición de estos pasos:
- – Comienza la siguiente ronda
- – Elige un bloque objetivo de finalidad: el mejor bloque que queremos que se finalice
- – Emite un voto sobre el objetivo de finalidad
- – Espera los votos de los demás validadores
- – Encuentra el bloque más común que aparezca en al menos 2/3 de las cadenas votadas por los validadores
- – Finaliza ese bloque
- – La ronda termina
La única flexibilidad que tiene un validador en este proceso se encuentra en el paso 2: su elección del bloque a votar como objetivo de finalidad. Esta elección se conoce como voting rule (regla de votación). En GRANDPA básico, cada validador solo elige la rama más larga de la relay chain que conoce y presenta el encabezado de esa cadena como su voto. Sin embargo, para el consenso de parachain introducimos una nueva regla de votación.
La regla de votación de GRANDPA para la comprobación de la aprobación dice que cada validador debe:
1. Elegir la rama más larga de la relay chain
2. Encontrar el bloque B más alto de la cadena, de forma que cada bloque entre el bloque finalizado actual y hasta B sólo desencadene la inclusión de bloques de parachain que el validador haya observado que han sido aprobados por suficientes validadores.
Desglosemos esto. Recuerda que uno de los objetivos principales es que la red sólo finalice los bloques de parachain que son realmente buenos y también que cada validador haga el menor trabajo posible para que la red pueda escalar. Así que por partes:
1.- Encontrar el bloque B más alto de la cadena: Queremos que cada nodo vote el bloque más alto posible que se ajuste a los otros criterios para que la finalidad avance lo más rápido posible.
2.- de tal manera que cada bloque entre el bloque finalizado actual y hasta B: La regla de votación necesita que los validadores voten en una cadena que sólo contenga buenos bloques de parachain. En GRANDPA, un voto a un bloque cuenta como un voto a todos sus antecesores, por lo que aunque el bloque 100 sólo contenga bloques buenos de parachain, los bloques 99 y 98 podrían no contenerlos. Por lo tanto, la regla de votación tiene que encontrar la cadena contigua más alta de bloques de relay chain que pase los otros criterios.
3.- sólo activa la inclusión de los bloques de parachain: Volviendo a la sección sobre la extensión de parachain, lo que se quiere decir es que los bloques de parachain hayan quedado disponibles en virtud de los certificados de disponibilidad en el bloque de la relay chain y que los bloques de la parachain se han añadido a la parachain. Los bloques de parachain que aún no están disponibles no cuentan como parte de la parachain todavía.
4.- que el validador ha observado que ha sido aprobado por suficientes validadores: Esto se refiere al mecanismo de comprobación de la aprobación que describiremos más adelante, que es una forma de que los validadores tengan una gran confianza en que un bloque de parachain es bueno sin tener que comprobarlo ellos mismos confiando en las comprobaciones de los demás.
A continuación se muestran 3 ejemplos de cómo se aplica la regla de votación para seleccionar qué bloques se votan para ser finalizados.
En el primer ejemplo, se muestra la propiedad de contigüidad, así como el hecho de que elegimos un antecesor de la mejor cadena.
En el segundo ejemplo, votamos el bloque finalizado porque ninguna de las dos cadenas es finalizable.
En el tercer ejemplo, toda la mejor cadena es finalizable, por lo que elegimos votar por ella.
Por último, cabe señalar que esta regla de votación es un proceso que se ejecuta en cada validador y que todos ellos pueden tener diferentes opiniones sobre el objetivo de la finalidad en función de los bloques de la relay chain y los mensajes de aprobación que han visto. Pero esto encaja perfectamente con GRANDPA: si todos los validadores honestos ejecutan esta regla de votación, ningún bloque de la relay chain puede ser finalizado a menos que 2/3 de los nodos estén de acuerdo en que es finalizable.
La comprobación de la aprobación ralentiza un poco la finalidad, pero sólo un poco. Se permite que las parachains tengan unos 3 segundos de tiempo de ejecución, y se tarda alrededor de 1 segundo en recuperar los datos y unos segundos más para que los mensajes sean gossiped. En el supuesto optimista, esto significa que añade unos 5 segundos extra a la finalidad. Y esta es la verdadera finalidad, con todo el peso del Polkadot detrás.
Así que vamos a entrar en el proceso de comprobación de aprobación y lo que los nodos están haciendo realmente para tener una idea de qué bloques de parachain son buenos y han sido comprobados por suficientes validadores.
Propiedades y seguridad de la comprobación de aprobación
La comprobación de aprobación es un subprotocolo que los validadores ejecutan para cada bloque de parachain.
Cada nodo validador ejecuta un proceso de comprobación de aprobación para cada bloque de parachain en cada bloque de la relay chain. Este proceso tiene algunas propiedades:
- El proceso en cualquier nodo particular da como resultado “bueno” o se detiene.
- Si el bloque de parachain es válido (es decir, pasa las comprobaciones), acabará saliendo “bueno” en los nodos honestos.
- Si el bloque de parachain es inválido, sólo dará un resultado “bueno” en los nodos honestos con baja probabilidad
Hay que tener en cuenta que la “baja probabilidad” en el caso inválido es algo así como 1 entre varios miles de millones, dependiendo de variables como el número de validadores y el número de verificadores mínimos. Esta no es la versión criptográfica de la baja probabilidad, pero es adecuada para la criptoeconomía.
El argumento de seguridad de Polkadot se basa en la Ruina del Jugador. Si bien es cierto que un atacante que pueda realizar miles de millones de intentos para aplicar fuerza bruta al proceso eventualmente tendría éxito, nosotros combinamos este proceso con un sistema de slashing (recorte) que garantiza que cada intento fallido vaya acompañado de un slash de todo el stake de los validadores atacantes. Polkadot es una red de proof-of-stake, y en el momento de escribir este artículo, cada validador está respaldado por aproximadamente 2 millones de DOT de stake. Lo más probable es que cada intento fallido suponga el slash de 10 o 20 validadores. Pero incluso si sólo se recorta un validador, es evidente que los fondos de un atacante se agotarían rápidamente antes de tener éxito.
Logramos esto con algunas otras propiedades de la comprobación de aprobación:
- Las asignaciones de los validadores para comprobar un bloque de parachain son secretas hasta que son reveladas por ellos mismos.
- Las asignaciones de los validadores se generan de forma determinística.
- Los validadores transmiten su intención de comprobar un bloque de parachain antes de recuperar los datos necesarios para realizar esas comprobaciones.
- Cuando los validadores transmiten su intención de comprobar un bloque de parachain y luego desaparecen, esto hace que más validadores honestos comiencen a comprobarlo.
La propiedad 1 garantiza que un atacante no sepa a quién hacer la DoS para evitar que compruebe un bloque.
La propiedad 2 asegura que incluso si el atacante ha tenido un “sorteo” afortunado y tiene suficientes nodos maliciosos para convencer a los nodos honestos de que algo ha sido comprobado, lo más probable es que haya nodos honestos que hagan las comprobaciones junto a ellos, y esos nodos honestos darán la alarma.
La propiedad 3 garantiza que los nodos honestos no se revelen accidentalmente como verificadores solicitando datos a nodos maliciosos y que luego sean desconectados por el adversario sin que nadie lo note, es decir, que si el atacante intenta silenciar a los verificadores lo notarán los demás.
La propiedad 4 asegura que los nodos que parecen haber sido DoSed serán reemplazados por más nodos. La comprobación de aprobación pretende ser como la hidra: si cortas una cabeza, aparecen dos más.
En las próximas secciones se explicará con más detalle cómo funciona realmente la comprobación de aprobación.
¿Qué comprueban los validadores?
El objetivo de los validadores aquí es decidir si los validadores de respaldo estuvieron involucrados en algún mal comportamiento. Esto requiere 3 pasos:
1. Descargar los datos del PoV para comprobar el bloque. Esto se hace obteniendo 1/3 de los chunks y combinándolos para formar los datos completos.
2. Asegurar de que los datos PoV corresponden a una transición de estado válida de parachain.
3. Asegurar que todas las salidas comprometidas por el encabezado del bloque de parachain coinciden realmente con las salidas de la ejecución del bloque de parachain.
La recuperación de la disponibilidad nunca debería fallar bajo el supuesto de que >2/3 de los nodos son honestos y se han comprometido a tener su chunk de datos. Por ello, la comprobación de la aprobación sólo se realiza para los bloques de parachain disponibles.
Sin embargo, los pasos (2) y (3) pueden fallar. Cuando el paso (2) falla, indica que la propia transición de estado es basura. Cuando el paso (3) falla, significa que la transición de estado tuvo éxito, pero la información registrada en la relay chain sobre las salidas de la transición de estado era falsa.
Un caso importante a tener en cuenta en el paso (3) es que el encabezado del bloque de parachain contiene un compromiso con todos los chunks de la codificación de borrado. Hacemos que los validadores hagan una comprobación extra después de recuperar los datos del PoV, que consiste en volver a convertir el PoV en su forma de codificación de borrado y asegurarse de que el compromiso en el encabezado coincide con todos los chunk. Si no hay coincidencia, esto evita un tipo de ataque en el que un atacante puede elegir selectivamente qué validadores pueden recuperar los datos. La forma en que funciona el ataque es la siguiente: un atacante divide los datos en chunks y sustituye todos los chunks menos 1/3 por basura. Distribuye 1 chunk válido a un validador honesto, y da a otro 1/3 de validadores datos basura. El 1/3 malicioso de los validadores se queda con el resto de los chunks con datos válidos. Esto significa que hay suficientes validadores (2/3 + 1) para considerar los datos disponibles, pero si los validadores maliciosos se niegan a responder a las peticiones sobre su 1/3 de chunks buenos, entonces sólo habrá basura disponible. Comprobar que la recodificación de los datos coincide realmente con el compromiso derrota este ataque de forma contundente.
Si cualquiera de los pasos (2) o (3) fallan, el verificador levantará una disputa y escalará el bloque a todos los validadores para que realicen las mismas comprobaciones. Volveremos a hablar de las disputas más adelante para discutir exactamente lo que esto significa.
Cuándo comprobar
Una de las claves para entender el sistema de comprobación de la aprobación es que cada validador tiene asignado comprobar cada bloque de parachain, pero es una cuestión de cuándo lo comprueban. Si un validador ve un bloque de parachain como aprobado antes de que sea su momento de comprobarlo, simplemente no lo comprueba y sigue adelante.
El tiempo se divide en ticks diferenciados de 0,5 segundos a partir de la Unix Epoch. La elección de 0,5 segundos se basa en el tiempo esperado que tardan los mensajes pequeños en propagarse por la red de chismes (gossip).
El tiempo en que un validador debe comprobar un bloque de parachain se expresa en un delay tranche (tramo de retardo), que es relativo al bloque de parachain. Los delay tranches van de 0 a MAX_TRANCHES, y corresponden al número de ticks después de que un nodo tenga conocimiento de que el bloque de parachain está disponible. Los nodos tienen visiones ligeramente diferentes de a qué tramo de ticks corresponde el 0. MAX_TRANCHES es un parámetro de protocolo que determina el tiempo que se tarda en comprobar cada bloque de parachain. Si se fija demasiado pequeño, es posible que se seleccionen más verificadores de los necesarios y, por tanto, se desperdicie el esfuerzo. Si se establece demasiado grande, significa que se tarda demasiado en comprobar los bloques de parachain. Como referencia, este parámetro está ajustado a 89 en Polkadot y Kusama en el momento de escribir este artículo.
Los ticks son una medida diferenciada del tiempo, basada en incrementos de medio segundo a partir de la Unix Epoch.
El tranche 0 es especial, en el sentido de que el número esperado de verificadores en el tranche 0 está diseñado para ser aproximadamente igual a MIN_CHECKERS, que es un parámetro de protocolo que especifica la cantidad mínima de verificaciones que se requieren antes de que un bloque de parachain pueda considerarse aprobado por el procedimiento de verificación de aprobación.
Los validadores que formaban parte del grupo de respaldo del bloque de parachain no pueden participar en la comprobación de aprobación porque sus comprobaciones serían redundantes. Todos los demás validadores ejecutan un cálculo VRF localmente para determinar en qué delay tranche (tramo de retraso) deben comprobar.
Asignaciones, aprobaciones y ausencias
Hay dos tipos de mensajes que los validadores envían en la comprobación de aprobaciones: Assignments (asignaciones) y Approvals (aprobaciones). Las asignaciones se utilizan para comunicar la intención y la elegibilidad para comprobar un bloque de parachain, y un mensaje de aprobación indica que un bloque de parachain ha superado todas las comprobaciones.
Cada validador genera inmediatamente una asignación para comprobar el bloque de parachain utilizando un VRF y el ID de la parachain y la credencial BABE del bloque de la relay chain como entrada. Los validadores mantienen su asignación en privado hasta que la necesitan. Cada asignación se asocia de forma única y determinística con un delay tranche (tramo de retraso), que indica el tramo de retraso cuando el validador es asignado para comprobar el bloque de parachain.
El VRF es importante porque significa que la asignación es verificable por los receptores y que el validador asignado no tiene ninguna influencia sobre el tramo de retardo al que está asignado. Los validadores sí tienen cierta influencia indirecta a través de ataques más sofisticados que implican bifurcar deliberadamente la relay chain cuando la aleatoriedad de BABE es favorable, pero eso lo dejaré para otro artículo.
Una aprobación es un simple mensaje, firmado por el validador emisor, que indica que un bloque de parachain ha pasado las comprobaciones.
Cuando un validador comienza a comprobar un bloque de parachain, lo primero que hace es chismear (gossip) su asignación a otros validadores. Esto informa a los otros validadores para que esperen el correspondiente mensaje de aprobación. Una vez que el validador ha terminado la comprobación, emite un mensaje de aprobación. Si el mensaje de aprobación no llega dentro de NO_SHOW_DURATION, los demás nodos consideran que el validador inicial no se ha presentado (no show). Los no-show pretenden indicar que un adversario ha observado la intención del validador de comprobar el bloque de parachain y ha intentado silenciarlo. NO_SHOW_DURATION es un parámetro de protocolo que actualmente está establecido en 12 segundos en Polkadot.
Aquí hay un diagrama que muestra 3 casos: un no-show, una asignación cumplida y un cumplimiento tardío. El último caso es especialmente importante, porque muestra cómo los validadores pueden “volver de entre los muertos” y hacer que su aprobación cuente incluso después de haber sido considerado como un no-show.
Llegar al sí: la programación y la máquina de estado de aprobación
Esta última sección sobre el protocolo de comprobación de aprobación detallará la state machine (máquina de estado) para la aprobación de un bloque de parachain.
Cada nodo validador mantiene un approval state (estado de aprobación) para cada bloque de parachain incluido (disponible). Las versiones del estado de los validadores pueden diferir debido a la sincronización y asincronía en la red. El estado nos permite responder a preguntas como:
- ¿Está aprobado el bloque de parachain?
2. ¿Es relevante una asignación con el tramo T?
3. En ausencia de otras entradas, ¿cuál es el siguiente punto en el tiempo en el que las respuestas a las preguntas (1) o (2) podrían haber cambiado?
El estado de aprobación puede actualizarse de 3 formas: al recibir una nueva asignación, al recibir una nueva aprobación o al avanzar el tiempo.
Los validadores ejecutan la máquina de estado hasta que la respuesta a la pregunta (1) sea “sí”. Después de cada entrada, utilizan la pregunta (2) para determinar si deben empezar a comprobar el bloque de parachain por sí mismos, viendo si su asignación es relevante. La pregunta (3) es necesaria sólo por motivos de optimización: los nodos suelen ejecutar miles de estas máquinas de estado en paralelo (una por cada bloque de parachain no finalizado) y es ineficiente sondearlas todas cada vez.
Lo que el estado contiene en realidad son 2 partes:
- Todas las asignaciones recibidas, ordenadas por tramo y anotadas con el tick en el que se observaron por primera vez.
- Todas las aprobaciones recibidas.
Un validador no incluye su propia asignación en el estado hasta que comienza la comprobación. Al producir una aprobación, un validador la incluye en el estado.
Esta es una representación visual del estado; es un objeto neutro que puede responder a preguntas basadas en qué asignaciones han entrado, cuánto tiempo ha pasado y qué aprobaciones han llegado.
Una de las operaciones más importantes en el estado de aprobación es averiguar qué asignaciones deben contarse. Tomamos los tramos de retraso en su totalidad. Las asignaciones siempre se agrupan con todas las demás asignaciones del mismo tramo de retraso. Un nodo nunca contará una asignación de un tramo de retraso sin contar todas las demás asignaciones del mismo tramo de retraso que conoce.
Una asignación se encuentra en uno de los tres estados siguientes:
- Pendiente: La asignación no tiene la aprobación correspondiente, pero fue emitida recientemente.
- Cumplida: La asignación tiene la aprobación correspondiente.
- No show (No presentado): La asignación no tiene la aprobación correspondiente y no fue emitida recientemente.
Las asignaciones no presentadas (no show) deben estar cubiertas por al menos un tramo no vacío. Es decir, cada asignación no presentada tiene que estar cubierta por al menos una asignación, pero, en principio, por más de una (según la parametrización).
La determinación del número de tranches (tramos) a tomar se hace con el siguiente procedimiento:
- Tomar tramos (tranches), empezando por el tramo 0, hasta que contengan al menos asignaciones MIN_CHECKERS.
- Tomar tramos no vacíos, uno por cada no-show. Si hay más no-show en esos tramos no vacíos, repetir el paso 2.
- Si se cumplen todas las asignaciones de no-show, se aprueba el bloque de parachain. Dicho de otro modo, si alguna de las asignaciones sigue pendiente, entonces el bloque de parachains no se aprueba.
Si en algún momento se agotan los tramos a tomar (el máximo es un parámetro del protocolo), el bloque no se aprueba. En la versión real de este protocolo, hay algunas restricciones adicionales con respecto a no tomar tramos que estén “en el futuro”, así como un tiempo de deriva basado en cada iteración del paso 2.
Este diagrama de flujo captura la lógica que cada validador ejecuta para determinar si un bloque de parachain está aprobado. Es importante tener en cuenta que esto sólo se basa en las asignaciones y aprobaciones que el validador ha visto realmente. Pueden existir asignaciones que cambien el resultado del procedimiento de recuento, pero si no han sido recibidas por el validador que ejecuta el procedimiento, no pueden ser consideradas.
Las principales conclusiones de este procedimiento son que las asignaciones para los tramos posteriores no se cuentan en absoluto si hay suficientes asignaciones tempranas y que los nodos que desaparecen en circunstancias misteriosas se sustituyen.
Aquí hay 4 ejemplos de resultados del procedimiento de recuento de aprobaciones:
Cada vez que un validador ejecuta este procedimiento de recuento de aprobaciones y descubre que se necesitan más asignaciones, comprueba si debe activar su propia asignación y comenzar la comprobación. El validador activa su asignación si:
- El validador no ha activado ya su asignación.
- El tramo de la asignación es relevante para el estado: o forma parte de un tramo que el estado ya contabiliza o el procedimiento de recuento se quedó sin tramos y la asignación no está en el futuro.
En resumen
El protocolo de comprobación de la aprobación es el principal mecanismo de detección de fraudes de Polkadot. Antes de que nada llegue a esta fase, nos hemos asegurado de que los datos necesarios para la comprobación están disponibles. Este mecanismo resulta en la aprobación o escalada de cada bloque de parachain, y ha sido diseñado para que un atacante DoS que intente eliminar a los validadores que comprueban sea reemplazado por aún más verificadores. La comprobación de aprobación es la hidra. Está diseñada para comerse a los atacantes y escupirlos por el otro extremo. A donde los envía es a un sistema que llamamos disputas: El Tribunal de Consenso de Polkadot (Polkadot Consensus Court of Law).
Disputas: discutiendo por dinero
Una disputa (dispute) se produce cuando dos o más validadores no están de acuerdo con la validez de un bloque de parachain. Mientras que la mayor parte del contenido anterior de este artículo se centra en el camino feliz, es decir, el caso en el que un bloque de parachain es realmente bueno, las disputas se refieren a la ruta de error en la que un verificador de aprobación detecta realmente que un bloque de parachain inválido está disponible.
El proceso de disputas es relativamente sencillo. Se ha diseñado para cumplir los siguientes objetivos:
- Determinar si el bloque de parachain es bueno o malo sometiéndolo a votación de todos los validadores.
- Si el bloque de parachain es malo, asegurarse de no finalizar o construir sobre cualquier bloque de relay chain que lo haga disponible.
- Asegurarse de que los perdedores de la disputa sean castigados como corresponde.
Principalmente, las disputas tratan de cumplir uno de los objetivos de alto nivel de Polkadot: asegurarse de que nunca se finalice nada malo.
Los validadores que participan en una disputa emiten votos en la categoría “a favor” o “en contra”. La participación es automática o explícita.
La participación es automática mediante la comprobación del respaldo (backing) y la aprobación (approval checking). Cuando un validador ha emitido un certificado de respaldo o un mensaje de aprobación para un bloque de parachain, cuenta automáticamente como si hubiera participado en la categoría “a favor”. De hecho, los validadores honestos guardan un registro de todos los mensajes recientes de respaldo y comprobación de aprobación que han recibido para poder presentar pruebas contra sus pares más adelante.
La gran mayoría de los validadores no son participantes automáticos. Estos validadores participan explícitamente, lo que significa que firman un voto para la categoría “a favor” o “en contra”. Lo hacen después de hacer las mismas comprobaciones que hace un verificador de aprobación, a saber:
- Descargar los datos del PoV.
- Validar la transición de estado
- Validar los compromisos con las salidas de la transición de estado
La participación no es obligatoria, pero una disputa no puede resolverse hasta que al menos 2/3 de los validadores hayan emitido un voto en un lado. Los validadores son recompensados por su participación y por estar en el lado mayoritario.
Hay penalizaciones de slashing para los perdedores de una disputa. Disputar un bloque de parachain que es realmente válido es una pérdida de tiempo y de ancho de banda, por lo que hay una pequeña penalización por ello. Presentar un bloque de parachain inválido es un ataque contra Polkadot, por lo que la penalización es del 100%.
Disputas remotas y locales
Las disputas son principalmente un proceso fuera de la cadena (off chain). Es decir, se producen a nivel de “las cadenas” y no a nivel de “la cadena”. Sin embargo, la bifurcación de la relay chain que finalmente se finaliza debe contener un registro de la disputa. Esto se debe a que el slashing es un proceso dentro de la cadena (on chain).
Cuando se produce una disputa, todos los votos se registran en cada bifurcación de la cadena para activar el slashing y crear un registro permanente de la disputa.
Una disputa remota, con respecto a una bifurcación de la relay chain, es aquella que hace referencia a un bloque de parachain que no fue incluido en esta bifurcación de la relay chain.
Una disputa local, con respecto a una bifurcación de la relay chain, es aquella que hace referencia a un bloque de parachain que fue incluido en esta bifurcación de la relay chain.
La razón por la que se tomó esta decisión es porque nos informa cuales bifurcaciones de la relay chain necesitan ser abandonadas. Cualquier bifurcación de la relay chain que registre una disputa local que concluya en contra del bloque de parachain debe ser evitada y no conservada por los validadores honestos. En otras palabras, los validadores honestos que observen que un bloque de parachain es malo iniciarán automáticamente un ataque del 51% contra las bifurcaciones de la relay chain que contengan el bloque de parachain malo.
El resultado final es que la bifurcación finalizada de la relay chain no contiene ningún bloque de parachain que haya perdido disputas. Sin embargo, cuando los validadores honestos construyen la nueva cadena y omiten el bloque de parachain malo, reproducen la disputa en la nueva bifurcación como una disputa remota. El castigo se conserva, pero los efectos del delito se borran de la historia.
Este diagrama muestra cómo un bloque de parachain en disputa es remoto o local en función de la bifurcación de la relay chain que estés mirando:
Disputas y Reglas de Consenso
Al igual que con la comprobación de la aprobación, las disputas vienen acompañadas de modificaciones en las reglas de participación del consenso para los validadores honestos. Estos cambios tienen dos objetivos principales:
- Evitar la finalización de cualquier bifurcación de la relay chain que haga referencia a un bloque de parachain malo.
- Evitar construir sobre cualquier bifurcación de la relay chain que haga referencia a un bloque de parachain malo.
Estos objetivos corresponden a cambios en el comportamiento de GRANDPA y BABE, respectivamente.
La regla de votación de GRANDPA es una modificación de la regla de votación de GRANDPA de comprobación de la aprobación. Establece:
- Elegir un bloque según la regla de votación de comprobación de la aprobación
- Encontrar el bloque más alto B en esa cadena, de manera que todos los bloques desde el último bloque finalizado y hasta B sólo desencadenen la inclusión de bloques de parachain que no tengan disputas en curso o hayan perdido disputas.
Esta regla es similar a la regla de votación de comprobación de la aprobación, pero vamos a desglosar las partes más importantes, que hacen que los validadores ignoren los bloques de la relay chain que activan la inclusión de los bloques de parachain:
- que no tengan disputas en curso: Esto indica a los validadores que eviten finalizar los bloques de parachains que están en disputa hasta que hayan participado suficientes validadores. En otras palabras, “más vale prevenir que curar”.
- que han perdido disputas: Si un validador ve que hay 2/3 de opiniones en contra de un bloque de parachain, ese validador nunca votará para finalizar un bloque de la relay chain que desencadene la inclusión para ese bloque de parachain.
En este diagrama, mostramos algunos ejemplos de cómo se aplicaría la regla de votación de disputas GRANDPA a una cadena:
También hay una regla de selección de cadenas BABE (autoría de bloques) que sirve para el segundo objetivo. Normalmente, BABE indica a los validadores que amplíen la relay chain construyendo sobre el bloque de la relay chain que tenga el mayor peso, que es análogo a la altura. La regla modificada de selección de cadenas de BABE establece:
- Los bloques de la relay chain se consideran viables si están finalizados o si su parent block es viable y cada bloque de la relay chain que desencadena la inclusión es indiscutible o ha ganado una disputa.
- Un bloque de relay chain es una hoja viable si no tiene children viables
- Los validadores deben construir sobre la hoja viable con el mayor peso que conozcan.
La implicación de la regla de selección de la cadena BABE es que los validadores honestos abandonarán las bifurcaciones de la relay chain que desencadenen la inclusión de cualquier bloque de parachain que se considere inválido, incluso si eso significa construir temporalmente en una cadena más corta.
El diagrama siguiente muestra ejemplos de cómo la regla de selección de cadenas de BABE requiere que los validadores abandonen y dejen de construir sobre cadenas que contienen bloques de parachain que han perdido disputas. Esto hace que ataquen en un 51% la rama mala de la relay chain.
En la práctica, esto se traduce en un retroceso corto y automatizado de la relay chain. Aquí un ejemplo:
- En el bloque 1a, se incluye un bloque de parachain P.
- En el tiempo en que se construye el bloque 3a, el bloque de parachain P ha sido disputado y encontrado inválido.
- Los validadores honestos empiezan a ignorar el bloque 1a y cualquier hijo de 1a. En su lugar, construyen una nueva cadena comenzando con un bloque alternativo 1b que no incluye el bloque de parachain inválido P.
- Estos validadores honestos publican los mensajes de disputa relacionados con el bloque de parachain P en la nueva bifurcación de la relay chain, lo que garantiza que los respaldos de P sean recortados. Una vez que se construye 4b, se supera la cadena original y se finaliza 1b.
El retroceso es posible porque los validadores honestos no finalizan 1a hasta que es aprobada, y el proceso de aprobación es lo que ha suscitado la disputa. Una vez que se disputa P, los validadores dejan en suspenso la finalización de 1a. Cuando P pierde la disputa, los validadores se niegan a finalizar 1a bajo cualquier circunstancia.
En resumen, la lógica de las disputas es un medio para garantizar que el mal comportamiento detectado se castigue de forma contundente y que la relay chain se reorganice para evitar por completo el bloque de parachain malo. Las disputas y las reglas de selección de la cadena asociadas son las principales cosas que diferencian a Polkadot de un rollup optimistic normal. Los rollups optimistic se ejecutan encima de una cadena sobre la que no tienen influencia en la finalidad o la elección de fork, lo que significa que tienen que ser extremadamente conservadores sobre el riesgo de finalizar cualquier bloque que sea malo y, por lo tanto, imponen largos períodos de fraude y duraciones de withdrawal (días o semanas).
En Polkadot, el protocolo de disputas y las reglas de selección de la cadena significan que la finalidad simplemente se retrasa unos segundos cuando una disputa está en curso y la cadena puede construirse alrededor del bloque malo. La finalidad sigue siendo rápida, y la finalidad sigue siendo segura.
Todo junto
Este post ha sido una introducción profunda en el consenso de la blockchain y cómo hemos aplicado esos conceptos para construir Polkadot en conjunto. Una gran parte de nuestra metodología de diseño ha girado en torno a asegurar que las cosas funcionen rápidamente cuando las condiciones de la red son buenas, pero correctamente cuando las condiciones de la red son malas. La mayor parte del tiempo, no habrá validadores que ataquen. Las latencias de la red serán bajas y el ancho de banda será alto. En estas condiciones, la aprobación y la finalidad pueden producirse en unos pocos segundos. Pero cuando hay validadores que atacan o las condiciones de la red son malas, la finalidad se ralentizará en consecuencia y la relay chain tiene el poder de reorganizarse alrededor de los bloques de parachain malos.
Hemos estado trabajando en este conjunto de protocolos, de una forma u otra desde el verano de 2016. Es increíblemente gratificante ver estas cosas implementadas y funcionando en redes activas y altamente descentralizadas.
El problema del escalamiento de la blockchain solo ha empeorado desde que nos embarcamos en este viaje hace varios años. Hemos visto una serie de enfoques, pero muchos de ellos carecen de seguridad o descentralización. Polkadot, a través de sus sistemas de respaldo (backing), disponibilidad (availability), comprobación de aprobación (approval checking) y disputas (disputes), es una solución práctica que proporciona escalabilidad, descentralización y seguridad.
Sobre el desarrollo del protocolo
(Siguen las opiniones personales)
Construir sistemas de software es una lucha constante entre ideales, pragmatismo, estética y tiempo. La realidad nunca se ajusta al ideal. Nada es perfecto, pero las cosas pueden ser buenas.
Existe una desconexión entre la versión idealizada de un protocolo y las implementaciones que finalmente se ejecutan en las computadoras. Es similar a la diferencia entre un personaje de una obra de teatro y la encarnación de ese personaje por un actor. Los servidores de todo el mundo se pondrán el traje de nuestros validadores, pero nunca se convertirán en los Validadores de nuestro protocolo, por mucho que lo intenten.
El desarrollo del protocolo es un emprendimiento importante. Requiere mucho tiempo, energía y concentración. Requiere la voluntad de ignorar la gran mayoría de las cosas que ocurren en los márgenes. Estos sacrificios son arquetípicos: una obra sólo puede crearse mediante la ofrenda de todo lo que no es. Construir algo consiste en orientar los símbolos en relación con los demás. Y lo que es más importante, construir requiere la voluntad de fracasar al hacerlo. Como desarrolladores de protocolos, no tenemos más opción que fracasar. Pero al hacerlo nos encontramos con lo absurdo, y encontramos el sentido.
Los medios de comunicación de Internet fomentan los mensajes de construcción principalmente como un medio para conseguir un fin. Se nos alienta a construir como parte de algo más grande: negocios, sistemas financieros, movimientos sociales y declaraciones políticas. Es importante basar estos objetivos en lo artesanal y en la simple alegría de haber construido algo no sólo funcional, sino impregnado de cuidado y elegancia. El esfuerzo por construir cada pieza de un sistema para que esté alineada con las demás es una fuente de orgullo, y merece la pena incluso a costa de otras recompensas materiales.
Llevamos más de 5 años construyendo los protocolos aquí descritos, y he decidido terminar este post de esta manera para responder a la pregunta que muchos lectores se harán: “¿Por qué alguien pasaría 5 años haciendo esto?”. Este es un mensaje para todos los nuevos integrantes del espacio cripto. Esto es para todos los que han estado montando las olas desde las oleadas de 2020. Si te encuentras buscando un santuario a la avaricia y la contienda, existe, y ha estado aquí todo el tiempo.