Use esta página para dimensionar una máquina de pruebas, para entender por qué una transferencia tarda más de un minuto y por qué el espacio en bloque, y no el cómputo, limita el rendimiento, y para saber qué se rompe cuando cambia el sistema de pruebas. Todo lo que un validador acepta está respaldado por una prueba que él mismo verificó.
Qué enuncia una prueba
Una sola relación, para todos los programas que ejecuta la cadena:
Este programa RV32IM, iniciado en
base_pc, ejecutado sobre un vector de entrada privada comprometido porH_INy un segmento de entrada pública comprometido porH_PUB, se detuvo en un máximo de2ᵗ − 1ciclos, gastó como máximoGAS_LIMITde gas y publicó estas ocho palabras de salida.
El programa se identifica por su resumen en el circuito, hc; el verificador nunca ve una palabra de instrucción. Una transferencia protegida es esa relación aplicada al guest de paquete de activos ocultos, un programa de 4 entradas y 4 salidas ensamblado a mano cuyo hc queda fijado en el archivo génesis como hc_bundle. La cadena 20 fija el guest v3 (guests::bundle_hidden_v3, 60af094a…6e3fce, desde la cadena 17). Las cadenas 14 y 15 fijaron v1 (83d3a370…cd0ef8) y la cadena 16 el v2 sin ramas (651043e2…839b). Desde la cadena 17, cada paquete lleva además una segunda prueba, la del guest de autorización (guests::auth, génesis hc_auth, 1e4e347f…5639c1): la prueba del paquete recibe la clave de visualización, y la prueba de autorización demuestra que el remitente posee la clave de gasto correspondiente. Esta es la autorización dividida, y es lo que permite que un prover emparejado que solo posee una clave de visualización genere la prueba del paquete. El guest de activos ocultos reemplazó al guest bundle de 2 entradas y 2 salidas de las cadenas hasta la 13, que subsiste en el fullnode solo para pruebas y que ninguna cadena fija. Una llamada confidencial es la misma relación aplicada a un programa desplegado (Programas).
Cómo la wallet prueba un paquete
rand send <rand1…> <amount> realiza localmente el trabajo privado, y a la cadena solo llegan pruebas, compromisos, anuladores y sobres sellados:
- Escanear el árbol con la clave de visualización y elegir las entradas: como máximo dos notas de RAND que cubran el monto más la comisión en las ranuras 2–3 y, para una transferencia o quema de un token, como máximo dos notas del token en las ranuras 0–1, con las notas de RAND cubriendo solo la comisión. Una ranura de entrada sin usar es ficticia: monto 0, propiedad de la wallet, con su fallo de pertenencia enmascarado en el circuito y su anulador igualmente publicado. Desde el guest v2, el guest no tiene ramas: la ruta de una nota ficticia se procesa con hash a lo largo de los 32 niveles, igual que la de una nota real.
- Obtener el ancla de la cabecera (
rand_getAnchor) y el testigo de Merkle de 32 niveles de cada entrada real (rand_getWitness(index)), comprobando la raíz devuelta contra el ancla. - Construir cuatro salidas: la nota del destinatario y la nota de cambio en el grupo que mueve valor, presentes incluso con valor cero, y notas ficticias de monto cero en el resto, selladas con una clave desechable.
- Sellar cada salida en un sobre (ML-KEM-768 hacia el destinatario, más la clave de la transacción envuelta bajo el
ovkde la wallet), ensamblar la transacción completa con su acción y calcular su vinculación:blake3("rand-tx-bind-1" || …)sobre la transacción con las pruebas en blanco, ocho palabras (Transacciones). En la cadena 20, cuyo génesis fijabinding_domain: 1, esblake3("rand-tx-bind-2" || …)con el hash del génesis en primer lugar, luego el id de la cadena, de modo que una prueba hecha para una cadena no se verifica en ninguna otra, ni siquiera en una con el mismo id de cadena. Una wallet anterior a v0.6.8 usa la vinculación antigua, y la cadena 20 rechaza sus pruebas. - Autorizar: generar una sal nueva de 256 bits y probar el guest de autorización sobre su entrada privada de 16 palabras, la clave de gasto y la sal, con la vinculación como segmento de entrada pública, en el nivel 10. Deriva
nkde la clave de gasto y publicac = H(AUTH, nk ‖ salt), que el paquete porta comoauth_commit. - Probar el guest del paquete sobre su entrada privada de 1,212 palabras (la clave de visualización
nk, cuatro ranuras de entrada con sus rutas, el ancla, cuatro salidas,fee,burn_a,burn_r, el activo privadoA,time, la sal) con la misma vinculación como segmento de entrada pública, en el nivel 14. La prueba demuestra la propiedad, la pertenencia, que cada entrada real porta el activo de su ranura, los cuatro anuladores, el mismocy los dos balancesin₀ + in₁ = out₀ + out₁ + burn_aein₂ + in₃ = out₂ + out₃ + fee + burn_r. Esta es la prueba que un prover emparejado puede generar en lugar de la wallet; la prueba de autorización se genera en la propia máquina de la wallet. - Comprobar el resumen publicado de la prueba contra el calculado a partir del texto plano, y enviar
Transaction { chain_id, bundle, action: None }.
El orden importa desde la cadena 14: los sobres y la acción existen antes que las pruebas, porque las pruebas se comprometen con ellos. En una llamada, la prueba de la llamada se genera primero y también queda dentro de la vinculación. En una cadena hardening_v6, la prueba de la llamada se genera sobre una vinculación de llamada de la transacción con ambas pruebas en blanco (rand-call-bind-1 en las cadenas 16 a 19, rand-call-bind-2 con el hash del génesis en la cadena 20), que cubre los anuladores del paquete de comisión, de modo que no puede copiarse bajo otro paquete.
proving bundle (tier 14; about a minute on a laptop)…
proved in 98.3s: tier 14, 1423170 bytes
submitted transfer 4f2c… 1.5 RAND out, 98.499 RAND change, fee 0.001 RAND, anchored at height 192
La transcripción es el formato de salida de la wallet según la guía del fullnode en la cadena 14; el tamaño en bytes mostrado es el de una prueba de paquete con perfil de producción confirmada en la cadena 14. Desde la cadena 17, la wallet (v0.6.8 en la cadena 20 incluida) imprime dos líneas antes de estas, proving the spend authorisation on this machine (tier 10; seconds)… y authorisation proved in …: tier 10, … bytes, y redacta la línea del paquete como proving the bundle (tier 14; about a minute and a half on a laptop)….
La misma maquinaria paga cada acción, siempre con exactamente un paquete: un despliegue, una llamada, un registro de token o una emisión de token viajan en una autotransferencia de valor cero de RAND; una fianza, en un paquete que quema la apuesta mediante burn_r; y una quema de token o una quema de puente, en un paquete que quema el activo de las ranuras 0–1 (burn_a, burn_asset) y paga la comisión en RAND con las ranuras 2–3. El activo que mueve una transferencia es una palabra de testigo y no figura en ningún campo público.
Cuánto cuesta
Medido en el portátil de desarrollo (Apple Silicon, compilación release), las cifras que registran los propios documentos del fullnode:
| guest | palabras | ciclos | nivel | prueba | tamaño de la prueba (producción, 80 consultas) |
|---|---|---|---|---|---|
| guest de paquete v3 (cadenas 17 a 20) | — | 4,024 ciclos y 273 permutaciones Poseidon2 de margen en el presupuesto del nivel 14 | 14 | ≈ 100 s, 5.7 GB de pico; 102.5 a 134.0 s medidos en la cadena 18 (2026-09-30) | ≈ 1.50 MB; 1,494,151 a 1,504,260 bytes medidos en la cadena 18 (2026-09-30) |
| guest de autorización (cadenas 17 a 20) | — | 250 | 10 | ≈ 7 s; 6.6 a 19.9 s medidos en la cadena 18 (2026-09-30) | ≈ 1.37 MB; 1,364,940 a 1,375,371 bytes medidos en la cadena 18 (2026-09-30) |
| paquete de activos ocultos v1, 4 entradas y 4 salidas (cadenas 14 y 15) | — | por debajo del presupuesto del nivel 14, con unos 2,071 ciclos (13%) de sobra | 14 | ≈ 98–100 s, 5.7 GB de pico | ≈ 1.43 MB; 1,422,116 y 1,423,170 bytes medidos en la cadena 14 |
bundle, 2 entradas y 2 salidas (retirado; cadenas hasta la 13) | 3,811 | ≈ 9,160 | 14 | ≈ 100 s (94.6–97.9 s solo; 114 s cada uno al ejecutar dos a la vez) | 1,321,773 bytes medidos en la cadena 8 |
private_payment (una llamada) | pocas | < 1,000 | 10 | ≈ 7 s | ≈ 1.37 MB (fib en el nivel 10: 1,367,688 bytes con el conjunto de restricciones 7; 1,298,729 con el conjunto 6) |
| una llamada sin tabla de hash (libro mayor fuera de la cadena, cadena 18) | 773 | — | 14 | 114.8 s | 1,498,589 bytes |
| una llamada con la tabla SHA-256 (prueba de pasivos, cadena 18) | 994 | — | 14 | 122.9 s | 1,911,152 bytes |
| una llamada con la tabla Keccak (voto anónimo, cadena 18) | — | — | 12 | 29.2 s | 3,346,865 bytes |
La verificación es el costo del consenso, que pagan todos los nodos: unos 16 ms con una clave de verificación ya calentada, unos 230 ms la primera vez que se construye una clave para una forma dada. La clave de verificación no depende del contenido del programa: se indexa por (tier, program_log_height, input_log_height, keccak_log_height, sha256_log_height, public_log_height), de modo que un nodo construye una por forma y la reutiliza; para un programa desplegado, la clave se calcula una sola vez en segundo plano al desplegar (unos 2 s en un portátil, 7 s en un servidor de 2 vCPU). El paquete de 2 entradas y 2 salidas de la cadena 13 y anteriores declaraba la forma program 12, input 10, keccak 0, sha256 0, public 2, mem 16; una prueba de paquete de la cadena 14 declara public 4, la altura de las ocho palabras de vinculación, no lleva ninguna de las dos tablas de hash y se rechaza antes de construir cualquier clave de verificación si declara otro nivel, cualquiera de las dos tablas u otra altura pública. Desde el conjunto de restricciones 7, toda tabla declarada tiene al menos 2⁷ filas, de modo que una prueba de paquete de la cadena 20 declara public 7.
Una transacción en la chain 20 lleva por tanto unos 2,87 MB de prueba, la prueba del bundle y la prueba de autorización, y una llamada añade una tercera prueba. Cada una debe caber en el max_proof_bytes del génesis, 4.194.304 (4 MiB) en la chain 20, igual que en las chains 17 a 19, frente a los 8 MiB de las chains 13 a 16.
El guest del activo oculto cabe en el tier 14 solo porque lee sus entradas privadas en un bucle y fusiona las lecturas de hermanos de la comprobación de Merkle; escrita en el estilo anterior, desenrollado, la misma relación cae en el tier 16, con unos 400 s y 21–22 GB, lo que excluiría a las wallets de 16 GB.
La generación de pruebas está limitada por la CPU, y hoy la wallet usa el backend de CPU en todas las plataformas. En las ejecuciones de los tiers grandes el prover era monohilo: un droplet de 16 vCPU funcionaba al 99 % de un solo núcleo, y la memoria, no los núcleos, decidía si una prueba terminaba (memoria de la generación de pruebas). La opción --cuda de send, bond, call, deploy, bridge-mint y bridge-burn selecciona un backend de NVIDIA que requiere una compilación con --features cuda. Sus kernels se ejecutaron por primera vez en hardware real, una NVIDIA H100, el 2026-09-28 y coincidieron con la referencia de CPU, pero no hay PTX incluido en el checkout de circuits que vendoriza la versión, de modo que la compilación falla con no PTX for the GPU kernels hasta que se compilen los kernels. No se ha medido ninguna prueba de producción en un nodo de GPU de la flota. Deliberadamente no hay vuelta atrás a la CPU. Además, una llamada CUDA no puede sellar un sobre de entrada, porque la sal nunca sale del prover. El pico de memoria de una prueba de bundle de activo oculto en el tier 14 es de unos 5,7 GB (Production FRI, CPU); las clases de memoria mayores corresponden al intérprete y a las pruebas de recursión que se describen más abajo (≥ 64 GB y superiores).
Cómo verifica un nodo
La admisión ejecuta primero las comprobaciones baratas (Transacciones) y después:
- recalcula el bundle digest a partir del texto plano publicado (ancla, cuatro nullifiers, cuatro compromisos,
fee,burn_a,burn_r,burn_asset,time, elauth_commitdel bundle y una palabra de contaminación fija en cero) y exige que sea igual a lo que publicó la prueba: una prueba cuyo testigo rompió la relación publica un digest contaminado que no coincide con ningún texto plano. Algunas comprobaciones son estructurales (el guest aporta por sí mismo el emisor, el activo y el tiempo de una salida, de modo que un prover no puede elegirlos), y el activo privado no está en el digest; - decodifica la prueba y comprueba sus alturas declaradas frente al tier (
check_declared_heights), de modo que el límite de la cadena sobre la forma de una prueba es el del verificador. Antes de comprobar cualquier firma o prueba, se ejecuta un filtro de prueba canónica sobre cada transacción enviada o difundida por gossip (y, conhardening_v6, en la validación de bloques); desde fullnode v0.6.8 (audit v6, ZKV-4) ese filtro acota primero todo grado declarado a 25 bits (MAX_HONEST_DEGREE_BITS, el techo de la tabla de memoria más uno), de modo que una cabecera con un grado enorme ya no retiene a un nodo mientras se vuelve a derivar para ella el calendario de plegado honesto, y un pánico dentro del filtro rechaza esa transacción en lugar de detener el nodo; - calcula el binding de la transacción y ejecuta
Machine::verify_public(hc_bundle, &binding, proof): el verificador por lotes más la comprobación de queH_PUBes el digest de esas ocho palabras, de modo que una prueba copiada a una transacción con otra acción, otro sobre u otro chain id, o en la chain 20 al génesis de otra cadena, no se verifica (hasta la chain 13 el segmento estaba vacío y nada ataba una prueba a su transacción); - verifica la prueba de autorización frente a
hc_authy el mismo binding, y exige que elcque publica sea igual aauth_commit. Un bundle sin prueba de autorización se rechaza (AuthMissing), y también uno cuyocdifiere (AuthMismatch); - exige que el
GAS_LIMITde la prueba del bundle sea igual albundle_gas_limitdel génesis, 20.479, y el de la prueba de autorización a 1.279, los techos de cabecera de los dos guests (BundleGasLimit,AuthGasLimit); - para una llamada, hace lo mismo frente al
code_hashalmacenado del programa, con las palabras públicas del programa seguidas del binding de la llamada como segmento (unInvokede RPL-2 añade su transición como palabras de contexto, Programas), y luego comprueba la comisión frente al límite de gas que declara la prueba y sus bytes (Comisiones).
Una transacción enviada por RPC o gossip se verifica en uno de cuatro workers tras una cola de 64 posiciones, fuera del bucle de consenso, y solo se difunde por gossip una vez verificada; un token bucket por peer (ráfaga de 16, recarga de 4 por segundo) mide lo que un peer puede obligar a verificar a un nodo, y una caché de 8.192 entradas responde gratis a la repetición de una transacción rechazada de forma permanente. La verificación de las pruebas dentro de un bloque propuesto sigue ejecutándose en el bucle de consenso cuando se aplica el bloque. Un nodo que se sincroniza vuelve a verificar cada certificado y cada prueba de cada bloque antes de aceptarlo; nada se da por bueno porque un quórum lo firmara.
Tiers
| tier | presupuesto de ciclos (2ᵗ − 1) | filas de cpu | usado por |
|---|---|---|---|
| 10 | 1,023 | 2¹⁰ | el guest de autorización; private_payment, fib |
| 12 | 4,095 | 2¹² | |
| 14 | 16,383 | 2¹⁴ | el guest de bundle de activo oculto (y el guest bundle retirado); la mayor llamada |
| 16 | 65,535 | 2¹⁶ | la prueba de llamada EVM de la suite de pruebas; el approve de ERC-20 traducido (llamado en la chain 13) |
| 18 | 262,143 | 2¹⁸ | transfer y transferFrom de ERC-20, traducidos o interpretados |
| 20 | 1,048,575 | 2²⁰ | SPL Token, traducido o en el guest intérprete de sBPF |
Desde fullnode v0.5.6 (2026-09-25) se rechaza una prueba de llamada por encima del tier 14 (CallTierTooHigh) antes de construir una clave del verificador, y un bloque que lleve una es inválido; además, una llamada puede incluir como máximo 128 permutaciones Keccak-f y 128 compresiones SHA-256. Los tiers 16 a 20 siguen generando pruebas, pero solo fuera de la cadena: ninguna de las filas por encima del tier 14 puede llamarse en la chain 20, y la chain 20 rechaza el despliegue de un programa demasiado grande para cualquier llamada de tier 14, más de 8.180 palabras sin entrada pública (ProgramUncallable) (el presupuesto).
El prover elige el menor tier cuyo presupuesto cubre los ciclos más las filas del programa y del digest de entrada; una ejecución que no cabe falla antes de generar la prueba. Solo el tier es público. Cada escalón multiplica aproximadamente por cuatro el tiempo de prueba y añade un poco al tamaño de la prueba. En la chain 20 la comisión de una llamada sigue el límite de gas que declara su prueba y su tamaño en bytes, no el tier (Comisiones).
Conjuntos de restricciones y hard forks
Un conjunto de restricciones es el conjunto exacto de tablas, columnas, buses, valores públicos y parámetros de FRI que comprueba el verificador. Una prueba hecha con un conjunto no se verifica con otro, en ninguna dirección, y la repetición de arranque de un nodo vuelve a verificar todas las pruebas de su cadena, de modo que un nodo compilado con un conjunto distinto falla en la primera prueba y trunca. Por eso cada cambio del conjunto se corta como un nuevo chain id con todos los nodos en una misma compilación, y por eso rand_status informa hc_bundle y hc_auth, y un nodo cuya compilación no coincide con el génesis se niega a arrancar.
| conjunto | fecha | qué cambió |
|---|---|---|
| 2 | 2026-09-10 | cinco correcciones de solidez tras la primera revisión |
| 3 | 2026-09-11 | chip Poseidon2, hc en el circuito, la tabla del programa como testigo, memoria de subpalabra, RV32M, FRI reajustado a 27 consultas |
| 4 | 2026-09-11 | el compromiso de entrada con sal H_IN con su propia tabla; el cargador de binarios planos |
| 5 | 2026-09-12 | la tabla opcional keccak; altura de memoria declarada por la prueba; dos correcciones críticas de la auditoría zk; FRI de vuelta a 80 consultas; MAX_PROOF_BYTES a 2 MiB |
| 6 | 2026-09-14 | la tabla obligatoria public y H_PUB; la tabla opcional sha256; los guests intérpretes de EVM y sBPF como bibliotecas; 34 valores públicos. Lo que ejecutaron las chains 12 a 15. |
| 7 | 2026-09-28 | cada terminal LogUp cegado mediante el bus BLIND; cada tabla declarada con un mínimo de 2⁷ filas; comprobaciones de rango de 32 bits en las palabras de entrada, públicas y de sal; la syscall POSEIDON2_LEN (7); JALR pone a cero el bit 0 de su destino y exige funct3 = 0; claves del verificador con sal de key_derivation_v2. Lo que ejecutaron las chains 16 y 17. |
| 8 | 2026-09-29 | el medidor de gas: la columna GAS en la tabla cpu y el valor público GAS_LIMIT; 35 valores públicos. Lo que ejecutan las chains 18 a 20. |
Las chains 14 y 15 no cambiaron ninguna restricción. El nodo de la chain 15 guarda las 86 constantes de ronda de Poseidon2 como una tabla literal en lugar de un sorteo con semilla (auditoría ZKV-2): los mismos valores, de modo que no se movió ningún hash, digest ni prueba. Chain 14: el bundle de activo oculto es un guest nuevo (un hc_bundle nuevo) y el binding de la transacción usa el segmento público que el conjunto 6 ya ata en el circuito. Es igualmente un hard fork: cambiaron el formato de cable del bundle, el guest fijado y todos los identificadores de transacción, la nueva compilación rechaza una transacción de la chain 13 que lleve un bundle, y una wallet compilada antes del fork produce pruebas de segmento vacío que la cadena rechaza.
Las tres cadenas siguientes cambiaron cada una lo que es una prueba. La cadena 16 (fullnode v0.6.1, 2026-09-28) pasó al conjunto de restricciones 7, fijó el programa invitado de paquete sin ramas v2 y activó hardening_v6, después de que la revisión del 2026-09-27 mostrara que las tablas cortas y los terminales LogUp sin cegar filtraban datos privados (Cómo funciona la zkVM). Cambiaron todas las claves del verificador. La cadena 17 (v0.6.3, 2026-09-29) mantuvo el conjunto 7 y añadió la autorización dividida: el programa invitado de paquete v3, el programa invitado de autorización, dos campos nuevos en el formato de transmisión del paquete y el dominio de id de transacción rand-txid-3. La cadena 18 (v0.6.7-rc1, 2026-09-29) pasó al conjunto de restricciones 8 para el medidor de gas. Su coste medido en tamaño de prueba es inferior al 1 %. La cadena 19 (2026-10-01) es una re-génesis de la cadena 18 sobre la misma compilación v0.6.7 y no cambió nada en las pruebas. La cadena 20 (fullnode v0.6.8, 2026-10-01) mantiene el conjunto de restricciones 8 y los mismos programas invitados y claves del verificador, y cambia aquello a lo que una prueba queda vinculada: los vínculos de transacción y de llamada incorporan el hash de génesis (binding_domain: 1), una entrada pública que calculan la wallet y el libro mayor, de modo que ningún circuito cambió. Aun así es un hard fork, ya que las pruebas de una wallet v0.6.7 no se verifican en ella. Cada compilación rechaza las cadenas anteriores por su hash de génesis.
Dos notas de auditoría presentes en el código que conviene conocer: el verificador comprueba el valor público TIER contra la cabecera de la prueba y los bits de grado del lote, pero el propio circuito no lo restringe (auditoría ZL1, señalado para el siguiente conjunto en lugar de corregido, porque eliminarlo desplaza la disposición de los valores públicos); y H_IN es un compromiso visible para el programa invitado que el verificador no compara con un valor aportado por quien llama, por diseño.
Próximamente: agregación de bloques
Con unos 1.43 MB por prueba de paquete de activo oculto en las cadenas 14 y 15, un bloque de 4 MiB (el valor por defecto, y el de la cadena 12) contenía dos transferencias protegidas; con los ~1.3 MB del paquete de 2 entradas y 2 salidas contenía tres. Las cadenas 13, 14 y 15 elevaron el límite de bloque a 20 MiB (max_block_bytes), espacio para catorce. La cadena 20 mantiene 20 MiB, y allí una transferencia lleva unos 2.87 MB de prueba, de modo que un bloque contiene unas siete. El remedio que eligió el fullnode (2026-09-12) frente a la poda y frente a un bloque más grande es la agregación a nivel de bloque: una prueba recursiva por ventana sellada que verifica N pruebas de paquete, de forma que el historial sigue portando pruebas de extremo a extremo mientras se pueden descartar las pruebas en bruto. Está construida e integrada pero no activada, y desde la cadena 14 tiene que volver a medirse antes de poder activarse: la forma de paquete que admite se midió con el segmento público vacío (public 2), y un paquete vinculado a la transacción declara public 4, así que ningún paquete probado en la cadena 14 coincide con ella. Los conjuntos de restricciones 7 y 8 volvieron a mover la forma: ahora una prueba de paquete declara public 7 y publica 35 valores, de modo que la interfaz del agregado es de 35 palabras por prueba. Una compilación del nodo se niega a arrancar con cualquier génesis que incluya una sección aggregation, y las cadenas 14 a 20 se crearon sin ella. Un génesis con precios de gas dinámicos, como el de la cadena 20, también se rechaza junto a una sección aggregation. Desde fullnode v0.5.8 la prueba agregada también vincula a su agregador (auditoría AGG-2: el programa absorbe aggregate_binding(chain_id, aggregator, nonce)), por lo que el digest del programa de la forma admitida debe medirse en una compilación que incluya ese cambio. La activación también sigue a la espera de un ejercicio de extremo a extremo con un agregado falsificado contra el verificador de recursión corregido, que no se ha realizado, y de una decisión sobre la prueba de autorización: el programa de agregación verifica solo pruebas de paquete, por lo que en una cadena con autorización dividida sellar una ventana reduciría una transferencia de unos 2.87 MB a unos 1.37 MB, no a nada.
Lo que está construido:
- una segunda máquina nativa de Goldilocks (la VM de recursión,
randprotocol-rvm) cuyo programa verificador comprueba una prueba RV32 en unas 1.97 millones de filas en el nivel 21 (2,044,506 con el conjunto de restricciones 7), y un programa de agregación genérico en N sobre una ventana de pruebas de paquete; - dos roles: los validadores siguen siendo baratos en CPU y verifican un agregado por bloque sellado; los agregadores (un registro abierto, con fianza y con una dirección de pago protegida) prueban agregados en máquinas de clase GPU y cobran la parte de prueba de los paquetes cubiertos más un subsidio de bloque en RAND nuevo según un calendario de reducción a la mitad;
- cinco acciones (
RegisterAggregator,UnbondAggregator,WithdrawAggregator,SlashAggregator,Aggregate;SlashAggregatorsigue en el formato de transmisión y se rechaza, porque un agregado reintentado vuelve a firmar el mismo nonce y no es equivocación), una admisión en nueve pasos, el sellado y la poda de los paquetes cubiertos hasta unos 3 KB de campos públicos cada uno, una sincronización en forma sellada que cuesta a un nodo nuevo una verificación de recursión por ventana, los métodos RPCrand_getAggregate,rand_getAggregators,rand_getUnsealed,rand_getRawTransaction, y el demoniorand-node aggregate --watch.
Medido con el perfil FRI de prueba: un agregado con N=1 se probó en unos 26 minutos en un portátil con carga (327,035 bytes); un nodo nuevo aplicó un lote sellado de siete bloques en menos de un segundo con una verificación de recursión. Clases de máquina según el primer acotamiento: N=1 necesita ≥ 64 GB de memoria del host, N=2 ≥ 128 GB, N=3 ≥ 160 GB; el N ≥ 2 de producción corresponde al backend CUDA, que necesita un nodo con GPU que todavía no existe. Medido en una máquina de 256 GB con el conjunto de restricciones 7 (2026-09-28 y 29), el agregado con N=2 ocupó 133 GB, el de N=3 ocupó 221 GB, y la prueba de salida de producción (el programa verificador sobre una prueba interna) superó los 256 GB. Nada de esto se ha vuelto a medir con el conjunto de restricciones 8. Hasta que se active la agregación, ningún agregado sustituye a una prueba en la cadena 20: sus dos nodos de archivo conservan todas las pruebas en bruto, y sus validadores podan el historial de más de 24 horas.