Autor: toly, cofundador de Solana

Compilado por: Félix, PANews

 

Cada día se agregan aproximadamente 1 millón de cuentas nuevas a Solana, y el estado total ahora supera los 500 millones, con un tamaño de instantánea de aproximadamente 70 GB. A medida que el hardware mejora, estos números son totalmente manejables, pero el objetivo del tiempo de ejecución de SVM es proporcionar el acceso más barato al hardware y, para lograrlo, el estado y la memoria deben administrarse dentro de las limitaciones actuales del hardware.

ancho de banda PCI

A partir de 2024, el ancho de banda PCI más reciente puede alcanzar rendimientos de 0,5 Tbs a 1 Tb. O de 64 GB a 128 GB por segundo. Si bien suena enorme, si un transmisor lee/escribe 128 MB, un ancho de banda PCI de 128 GBps limitará el TPS de la cadena a alrededor de 1000. De hecho, la mayoría de los tx acceden a la memoria que se cargó recientemente y se almacenó en caché en la RAM. Un diseño ideal permitiría cargar 1000 txs con 128MB de estado nuevo, más 10k o más txs leyendo y escribiendo el estado en caché existente.

índice de cuenta

Para crear una cuenta nueva se requiere prueba de que la cuenta no existe actualmente. Por lo general, esto se hace automáticamente en cada validador, ya que cada validador tiene un índice completo de todas las cuentas actualmente activas. Incluso si los datos de la cuenta no se almacenan localmente, solo el hash de los datos, 500 millones de cuentas serían 32 bytes de clave + 32 bytes de hash de datos o 64 bytes por elemento, que son 32 GB. Esto es suficiente para asegurar la separación de la RAM y el disco.

tamaño de la instantánea

En ciertos tamaños de instantáneas, el tiempo necesario para iniciar en frío un nuevo sistema es suficiente para extender el tiempo de reinicio en el peor de los casos si se produce una falla de hardware en parte de la red. Las cosas cambian todos los días a medida que mejoran el ancho de banda y el hardware, y Solana no se acerca a ese límite, pero ese límite existe en cualquier momento.

descripción general

La memoria y el disco tienen diferentes características y limitaciones de rendimiento. Si SVM no diferencia, entonces las transacciones y los límites deben fijarse en el peor de los casos, lo que limita el rendimiento. Como mínimo, todas las claves de cuenta deben estar disponibles durante la ejecución de la transacción, y la cantidad total de cuentas afectará la utilización del ancho de banda PCIi de la RAM y el disco. Las instantáneas no se pueden hacer arbitrariamente grandes. La solución ideal es:

  • Permitir que más transmisiones que no requieran recursos PCI se empaqueten en fragmentos

  • Administrar el tamaño total del índice y el tamaño de la instantánea

Frío, aguacate, LSR. Un mal nombre suele ser señal de un buen diseño de software. A los ingenieros de Anza y Firedancer se les ocurrió la siguiente solución.

Frío

Todas las instancias administran de manera determinista la caché de tiempo de ejecución de la cuenta. En un nivel alto, se trata de una caché LRU de estado de acceso. Esta implementación facilita la verificación de cuentas durante la construcción y programación de bloques, sin la necesidad de bloquear o iterar el caché LRU. El caché se implementa mediante un mecanismo de contador muy simple.

  • El total de bytes cargados se rastrea como Bank::loaded_bytes:u64

  • Cada cuenta está etiquetada con el total acumulado actual account::load_counter:u64 cuando está en uso

  • Al cargar una cuenta, si Bank::loaded_bytes - Account::load_counter > CACHE_SIZE, la cuenta se considera una cuenta fría y su tamaño se calcula en función del LOAD_LIMIT por bloque

  • Las cuentas nuevas tienen un contador de carga de 0, por lo que todas las cuentas nuevas son cuentas frías.

  • El programador del líder trata LOAD_LIMIT como una marca de agua, similar al límite de CU de bloqueo de escritura.

Lo bueno de este diseño es que encaja naturalmente en los programadores actuales. Los usuarios sólo deben preocuparse por sus tarifas de prioridad. El programador tiene que lidiar con poner en la mochila todos los tx por debajo de LOAD_LIMIT y los límites de bloqueo de escritura de la cuenta. El tx de mayor prioridad se puede cargar primero y usar LOAD_LIMIT. Una vez que se alcanza este límite, todos los demás tx aún se pueden poner en un bloque. Por lo tanto, el validador puede maximizar la mitigación de la localidad de caché de txs.

Palta

Avacado consta de dos partes, compresión de estado y compresión de índice. Primero reemplace los datos de la cuenta con un hash, luego migre el índice de la cuenta a Binary Trie/patricia Trie. Las cuentas nuevas deben acreditar que no están en el "trie".

compresión de estado

El diseño aproximado es el siguiente:

  • Durante la asignación, cada cuenta está vinculada a X lamports por byte.

  • Si

  • La compresión es un proceso de varios pasos que se ejecuta a lo largo de una época.

  • Los datos de la cuenta se reemplazan con hashes (datos)

  • La clave de cuenta todavía está en estado

  • Error en la transacción que hace referencia a la cuenta comprimida

  • La descompresión requiere cargar datos similares al cargador

  • El costo de descomprimir debe ser el mismo que el costo de asignar una nueva cuenta.

Se estima que no se ha accedido al 75% de las cuentas en más de 6 meses y probablemente nunca se accederá a ellas. Al comprimirlos se ahorra un 50% en el tamaño de la instantánea.

Compresión de índice

Este es un problema más difícil de resolver. Solo con la compresión de estado, el validador aún posee todas las cuentas válidas posibles en el sistema. Para crear una nueva cuenta es necesario consultar esta base de datos. El costo para el validador de almacenar esta base de datos es alto, pero el costo para el usuario de crear una nueva cuenta es bajo. Asegúrese de que la nueva clave privada no entre en conflicto con las cuentas existentes.

Minería Trie binaria

  • Binary Trie se rastrea como parte de la instantánea

  • Los validadores que quieran ganar soles adicionales pueden crear una transacción que elimine los pares comprimidos cuenta-kv del estado y los agregue al Binary Trie.

  • Los usuarios pueden hacer esto a la inversa sin que se les permita hacerlo eliminando el kv del Trie durante la descompresión (esto puede requerir operaciones atómicas en la descompresión para facilitar el servicio de cuentas de compresión en segundo plano).

  • Para un validador, el tamaño de la raíz Trie es constante sin importar cuántos pares de kv contenga

  • Usando zkp, se pueden comprimir alrededor de 30 cuentas por tx

  • Suponiendo que solo haya un bloque por bloque, se necesitarían aproximadamente 80 días para compactar 500 millones de cuentas.

La clave de este proceso es que los validadores que realicen esta acción serán recompensados, pero no todos los validadores están obligados a realizar esta acción. Si todos los validadores tuvieran que hacer esto, entonces todos los validadores tendrían que mantener el contenido del Binary Trie actual, lo que significa que todo el estado tendría que ser parte de la instantánea. Un validador que quiera mantener el estado completo debe enviar una transacción que comprima las N cuentas en el índice en un intento.

Prueba de cuenta nueva

Para crear una nueva cuenta, el usuario deberá acreditar que la cuenta no existe en Trie. Un validador que mantiene todo el estado puede generar pruebas de que la cuenta no está en el Trie. Esto supone una carga para los usuarios, que siempre deben estar conectados a un gran proveedor estatal para generar estas pruebas.

Alternativamente, los usuarios pueden demostrar que su cuenta se creó con un hash PoH reciente. La forma más sencilla de respaldar esto es:

  • Generar nueva PKI

  • La dirección de la cuenta es hash (hash PoH más cercano, PKI::public_key)

Dado que las cuentas en el Trie primero deben someterse a una compactación estatal, esto requiere una época completa. Es imposible que cualquier cuenta en Trie utilice un hash PoH reciente para generar una dirección.

Otros métodos que podrían admitirse es que la creación de PKI en sí misma podría proporcionar una prueba de que la clave privada se creó con un hash (secreto oculto del usuario, hash PoH reciente).

LSR

Alquiler simple y ligero, también conocido como alquiler menos estúpido. ¿Cómo se fija el precio del costo de asignar nuevas cuentas y cómo se garantiza que las antiguas cuentas abandonadas eventualmente se compriman y reduzcan la carga general en el sistema y el precio para los nuevos usuarios?

Es necesario restablecer el sistema de alquiler (Rent). El alquiler significa que a las cuentas en su estado actual se les debe cobrar $X/byte/día, al igual que las cuentas en AWS pagan por el almacenamiento.

Curva de vinculación de la tasa de alquiler

Tarifa de alquiler = K*(tamaño_estado)^N

Independientemente del tamaño del estado actual, la tasa debe ser baja si es pequeña o muy alta si está cerca del límite de la instantánea.

Precio mínimo de vinculación de asignación

La cuenta debe existir durante al menos una época. Se requiere una asignación para que la cuenta pase al estado Caliente. Las cuentas activas deben existir durante el almacenamiento en caché.

Bono de cuenta nueva = Espacios de época * Tasa de alquiler * Cuenta::tamaño

Las cuentas nuevas deben tener al menos esta cantidad de importaciones en su saldo antes de poder crearlas.

Grabación de cuentas calientes

lruturnverrate = Tiempo promedio que cada cuenta pasa en la caché LRU, máximo 1 época. Este valor puede ser una constante o puede calcularse fuera de la cadena y reportarse al SVM como una constante ponderada de participación mediana.

compresión

Cuando (espacio actual - cuenta::creation_slot) * RentRate * cuenta::tamaño > cuenta::lamports, comprime la cuenta y graba todos los lamports.

La solución anterior debería abaratar el estado, ya que con el tiempo las cuentas no utilizadas eventualmente llegarán a Lamberts 0 y se comprimirán. Por lo tanto, se reducirá la sobrecarga de datos e incluso se reducirá la sobrecarga de indexación, lo que reducirá el tamaño del estado actual. Reducir el tamaño del estado reducirá el costo de la asignación supercuadrática.