Используйте эту страницу, чтобы подобрать машину для доказательства, понять, почему перевод занимает больше минуты и почему пропускную способность ограничивает место в блоке, а не вычисления, и узнать, что ломается при смене системы доказательств. Всё, что принимает валидатор, подкреплено доказательством, которое он проверил сам.
Что утверждает доказательство
Одно отношение для каждой программы, которую выполняет цепочка:
Эта программа RV32IM, запущенная с
base_pc, выполненная на приватном входном векторе, зафиксированном обязательствомH_IN, и открытом входном сегменте, зафиксированномH_PUB, остановилась не позднее чем за2ᵗ − 1тактов, израсходовала не болееGAS_LIMITгаза и опубликовала эти восемь выходных слов.
Программа идентифицируется своим внутрисхемным дайджестом hc; верификатор никогда не видит ни одного слова инструкции. Экранированный перевод — это данное отношение, применённое к гостевой программе пакета со скрытым активом, собранной вручную программе «4 входа — 4 выхода», чей hc закреплён в файле генезиса как hc_bundle. Цепочка 21 закрепляет гостевую программу v3 (guests::bundle_hidden_v3, 60af094a…6e3fce, начиная с цепочки 17; её дайджест не изменился с набором ограничений 9, а ключ верификатора изменился). Цепочки 14 и 15 закрепляли v1 (83d3a370…cd0ef8), а цепочка 16 — v2 без ветвлений (651043e2…839b). Начиная с цепочки 17 каждый пакет несёт и второе доказательство — гостевой программы auth (guests::auth, в генезисе hc_auth, 1e4e347f…5639c1): доказательство пакета принимает ключ просмотра, а доказательство auth показывает, что отправитель владеет ключом траты, стоящим за ним. Это разделённая авторизация, и именно она позволяет парному доказывающему, у которого есть только ключ просмотра, создать доказательство пакета. Гостевая программа со скрытым активом заменила гостевую программу bundle «2 входа — 2 выхода» цепочек до 13, которая сохранилась в fullnode только для тестов и ни одной цепочкой не закрепляется. Конфиденциальный вызов — это то же отношение, применённое к развёрнутой программе (Программы).
Как кошелёк доказывает пакет
rand send <rand1…> <amount> выполняет приватную работу локально, а в цепочку попадают только доказательства, обязательства, нуллификаторы и запечатанные конверты:
- Сканирование дерева ключом просмотра и выбор входов: не более двух нот RAND, покрывающих сумму плюс комиссию, в слотах 2–3, а при переводе или сжигании токена — не более двух нот токена в слотах 0–1, при этом ноты RAND покрывают только комиссию. Неиспользуемый входной слот — заглушка: сумма 0, принадлежит кошельку, сбой проверки включения в дерево маскируется в схеме, нуллификатор всё равно публикуется. Начиная с гостевой программы v2 она не содержит ветвлений: путь заглушки хешируется вверх по всем 32 уровням, как у настоящей ноты.
- Получение якоря головы (
rand_getAnchor) и 32-уровневого свидетельства Меркла для каждого настоящего входа (rand_getWitness(index)) с проверкой возвращённого корня по якорю. - Построение четырёх выходов: нота получателя и нота сдачи — в группе, которая перемещает стоимость, причём присутствующая даже при нулевой сумме, — и заглушки с нулевой суммой в остальных слотах, запечатанные на одноразовый ключ.
- Запечатывание каждого выхода в конверт (ML-KEM-768 для получателя плюс ключ транзакции, обёрнутый под
ovkкошелька), сборка всей транзакции с её действием и вычисление её привязки:blake3("rand-tx-bind-1" || …)по транзакции с обнулёнными доказательствами, восемь слов (Транзакции). Начиная с цепочки 20, в генезисе которой заданоbinding_domain: 1(цепочка 21 сохраняет его), этоblake3("rand-tx-bind-2" || …)с хешем генезиса в начале, затем идентификатором цепочки, поэтому доказательство, созданное для одной цепочки, не проходит проверку ни в какой другой, даже с тем же идентификатором цепочки. Кошелёк старше v0.6.8 использует старую привязку, и цепочки 20 и 21 отвергают его доказательства; в цепочке 21 кошелёк старше v0.8.0 отвергается ещё раньше, поскольку его доказательства относятся к набору ограничений 8 и не декодируются. - Авторизация: выбрать новую 256-битную соль и доказать гостевую программу auth на её 16-словном приватном входе — ключе траты и соли, — с привязкой в качестве открытого входного сегмента, на уровне 10. Она выводит
nkиз ключа траты и публикуетc = H(AUTH, nk ‖ salt), которое пакет несёт какauth_commit. - Доказательство гостевой программы пакета на её 1 212-словном приватном входе (ключ просмотра
nk, четыре входных слота с путями, якорь, четыре выхода,fee,burn_a,burn_r, приватный активA,time, соль) с той же привязкой в качестве открытого входного сегмента, на уровне 14. Доказательство показывает владение, включение в дерево, то, что каждый настоящий вход несёт актив своего слота, четыре нуллификатора, то жеcи два балансаin₀ + in₁ = out₀ + out₁ + burn_aиin₂ + in₃ = out₂ + out₃ + fee + burn_r. Это доказательство, которое парный доказывающий может создать вместо кошелька; доказательство auth создаётся на собственной машине кошелька. - Сверка опубликованного дайджеста доказательства с дайджестом, вычисленным из открытого текста, и отправка
Transaction { chain_id, bundle, action: None }.
Порядок важен начиная с цепочки 14: конверты и действие существуют раньше доказательств, потому что доказательства фиксируют их. Для вызова сначала создаётся доказательство вызова, и оно тоже входит в привязку. В цепочке с hardening_v6 доказательство вызова само создаётся над привязкой вызова — транзакции с обоими обнулёнными доказательствами (rand-call-bind-1 в цепочках с 16 по 19, rand-call-bind-2 с хешем генезиса начиная с цепочки 20), которая покрывает нуллификаторы пакета комиссии, поэтому её нельзя скопировать под другой пакет.
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
Протокол вывода — это формат вывода кошелька из руководства fullnode на момент цепочки 14; показанный размер в байтах — это размер доказательства пакета производственного профиля, зафиксированного в цепочке 14. Кошелёк начиная с цепочки 17, включая v0.8.0 в цепочке 21, выводит перед этими строками ещё две: proving the spend authorisation on this machine (tier 10; seconds)… и authorisation proved in …: tier 10, … bytes, а строку пакета формулирует как proving the bundle (tier 14; about a minute and a half on a laptop)….
Тот же механизм оплачивает каждое действие, всегда ровно с одним пакетом: развёртывание, вызов, регистрация токена или выпуск токена идут на нулевом самопереводе RAND, внесение залога — на пакете, сжигающем ставку через burn_r, а сжигание токена или сжигание в мосте — на одном пакете, который сжигает актив из слотов 0–1 (burn_a, burn_asset) и платит комиссию в RAND из слотов 2–3. Актив, который перемещает перевод, — это слово свидетеля, и он не содержится ни в одном открытом поле.
Во что это обходится
Измерено на ноутбуке разработки (Apple Silicon, релизная сборка); числа взяты из документов самого fullnode:
| гостевая программа | слов | такты | уровень | доказательство | размер доказательства (production, 80 запросов) |
|---|---|---|---|---|---|
| гостевая программа пакета v3 (цепочки с 17 по 20) | — | запас в бюджете уровня 14: 4 024 такта и 273 перестановки Poseidon2 | 14 | ≈ 100 s, пик 5,7 GB; от 102,5 до 134,0 s, измерено в цепочке 18 (2026-09-30) | ≈ 1,50 MB; от 1 494 151 до 1 504 260 байт, измерено в цепочке 18 (2026-09-30) |
| гостевая программа auth (цепочки с 17 по 20) | — | 250 | 10 | ≈ 7 s; от 6,6 до 19,9 s, измерено в цепочке 18 (2026-09-30) | ≈ 1,37 MB; от 1 364 940 до 1 375 371 байт, измерено в цепочке 18 (2026-09-30) |
| пакет со скрытым активом v1, «4 входа — 4 выхода» (цепочки 14 и 15) | — | в пределах бюджета уровня 14, с запасом около 2 071 такта (13%) | 14 | ≈ 98–100 s, пик 5,7 GB | ≈ 1,43 MB; 1 422 116 и 1 423 170 байт, измерено в цепочке 14 |
bundle, «2 входа — 2 выхода» (снята; цепочки до 13) | 3 811 | ≈ 9 160 | 14 | ≈ 100 s (94,6–97,9 s в одиночку; по 114 s при двух одновременно) | 1 321 773 байт, измерено в цепочке 8 |
private_payment (вызов) | мало | < 1 000 | 10 | ≈ 7 s | ≈ 1,37 MB (fib на уровне 10: 1 367 688 байт при наборе ограничений 7; 1 298 729 при наборе 6) |
| вызов без хеш-таблицы (внецепочечный реестр, цепочка 18) | 773 | — | 14 | 114,8 s | 1 498 589 байт |
| вызов с таблицей SHA-256 (доказательство обязательств, цепочка 18) | 994 | — | 14 | 122,9 s | 1 911 152 байт |
| вызов с таблицей Keccak (анонимное голосование, цепочка 18) | — | — | 12 | 29,2 s | 3 346 865 байт |
Проверка — это стоимость консенсуса, которую платит каждый узел: около 16 ms при прогретом ключе верификатора, около 230 ms при первом построении ключа для данной формы. Ключ верификатора не зависит от содержимого программы — он индексируется по (tier, program_log_height, input_log_height, keccak_log_height, sha256_log_height, public_log_height), — поэтому узел строит по одному ключу на форму и использует его повторно; для развёрнутой программы ключ вычисляется один раз в фоне при развёртывании (около 2 s на ноутбуке, 7 s на сервере с 2 vCPU). Пакет 2-in-2-out цепочки 13 и более ранних объявлял форму program 12, input 10, keccak 0, sha256 0, public 2, mem 16; доказательство пакета цепочки 14 объявляет public 4, высоту восьми связывающих слов, не несёт ни одной хеш-таблицы и отклоняется до построения любого ключа верификатора, если объявляет другой уровень, любую из таблиц или другую публичную высоту. Начиная с набора ограничений 7 каждая объявленная таблица содержит не менее 2⁷ строк, поэтому доказательство пакета цепочки 20 объявляет public 7.
Перевод в цепочке 20 поэтому нёс около 2,87 MB доказательств — доказательство пакета и доказательство авторизации, — а вызов добавлял третье доказательство сверх них; при наборе ограничений 9 доказательство без чипов вырастает примерно на 1–4 KB (более широкая таблица cpu), а размеры для цепочки 21 пока не измерены. Каждое должно укладываться в max_proof_bytes из genesis: 6 291 456 (6 MiB) в цепочке 21, увеличено при её выпуске ради доказательства авторизации приватной мультиподписи (оценка 3,4 MB и более, не измерено); 4 MiB в цепочках с 17 по 20; 8 MiB в цепочках с 13 по 16. В цепочке 21 пакет может нести второй вид доказательства авторизации — гостя мультиподписи (hc_auth_multisig, уровень 18), который реестр отличает по заголовку, объявленному доказательством (Транзакции).
Гость скрытого актива укладывается в уровень 14 лишь потому, что читает свои приватные входы в цикле и объединяет чтения соседних узлов при проверке Merkle; в прежнем развёрнутом стиле то же соотношение попадает на уровень 16, около 400 s и 21–22 GB, что исключило бы кошельки с 16 GB.
Доказательство ограничено CPU, и сегодня кошелёк использует бэкенд CPU на всех платформах. В прогонах на больших уровнях доказывающий был однопоточным: дроплет с 16 vCPU работал на 99 % одного ядра, а завершится ли доказательство, решала память, а не число ядер (память для доказательства). Флаг --cuda у send, bond, call, deploy, bridge-mint и bridge-burn выбирает бэкенд NVIDIA, для которого требуется сборка с --features cuda. Его ядра впервые запустились на реальном оборудовании, NVIDIA H100, 2026-09-28 и совпали с эталоном на CPU, но в checkout схем (circuits), который вендорит релиз, не закоммичен ни один PTX, поэтому сборка завершается ошибкой no PTX for the GPU kernels, пока ядра не скомпилированы. Ни одно боевое доказательство не измерялось на GPU-узле парка. Откат на CPU намеренно не предусмотрен. Вызов через CUDA также не может запечатать входной конверт, поскольку соль никогда не покидает доказывающего. Пиковая память для доказательства пакета скрытого актива уровня 14 составляет около 5,7 GB (FRI боевой конфигурации, CPU); более крупные классы памяти относятся к доказательствам интерпретатора и рекурсии, описанным ниже (≥ 64 GB и выше).
Как узел проверяет
Приём сначала выполняет дешёвые проверки (Транзакции), затем:
- пересчитывает дайджест пакета из опубликованного открытого текста (якорь, четыре нуллификатора, четыре обязательства,
fee,burn_a,burn_r,burn_asset,time,auth_commitпакета и слово-пометку, зафиксированное в нуле) и требует его равенства тому, что опубликовало доказательство, — доказательство, чей свидетель нарушил соотношение, публикует испорченный дайджест, не совпадающий ни с каким открытым текстом. Некоторые проверки вместо этого структурные (гость сам задаёт отправителя, актив и время выхода, так что доказывающий не может их выбрать), а приватный актив в дайджест не входит; - декодирует доказательство и сверяет его объявленные высоты с уровнем (
check_declared_heights), так что границу формы доказательства в цепочке задаёт верификатор. Прежде чем проверяется любая подпись или доказательство, на каждой отправленной или разосланной по gossip транзакции выполняется отсев канонического доказательства (а приhardening_v6— и при валидации блока); начиная с fullnode v0.6.8 (аудит v6, ZKV-4) этот отсев сначала ограничивает каждую объявленную степень 25 битами (MAX_HONEST_DEGREE_BITS, потолок таблицы памяти плюс один), так что заголовок с огромной степенью больше не задерживает узел, пока для него заново выводится честное расписание свёртки, а паника внутри отсева отклоняет эту транзакцию, а не останавливает узел; - вычисляет привязку транзакции и запускает
Machine::verify_public(hc_bundle, &binding, proof)— пакетный верификатор плюс проверку того, чтоH_PUBявляется дайджестом этих восьми слов, так что доказательство, скопированное на транзакцию с другим действием, другим конвертом или другим идентификатором цепочки, а с цепочки 20 — на genesis другой цепочки, не проходит проверку (до цепочки 13 включительно сегмент был пуст, и ничто не привязывало доказательство к его транзакции); - проверяет доказательство авторизации по
hc_authи той же привязке и требует, чтобы публикуемое имcравнялосьauth_commit. Пакет без доказательства авторизации отклоняется (AuthMissing), как и пакет, у которогоcотличается (AuthMismatch); - требует, чтобы
GAS_LIMITдоказательства пакета равнялсяbundle_gas_limitиз genesis, 20 479, а у доказательства авторизации — 1 279, то есть потолкам заголовков двух гостей (BundleGasLimit,AuthGasLimit); - для вызова делает то же самое относительно сохранённого
code_hashпрограммы, с публичными словами программы, за которыми следует привязка вызова, в качестве сегмента (InvokeRPL-2 добавляет свой переход как контекстные слова, Программы), затем проверяет комиссию относительно лимита газа, объявленного доказательством, и его размера в байтах (Комиссии).
Транзакция, поданная по RPC или gossip, проверяется на одном из четырёх воркеров за очередью глубиной 64, вне цикла консенсуса, и пересылается дальше лишь после успешной проверки; корзина токенов на каждого пира (всплеск 16, пополнение 4 в секунду) ограничивает то, что пир может заставить узел проверять, а кэш на 8 192 записи отвечает на повтор окончательно отклонённой транзакции бесплатно. Проверка доказательств внутри предложенного блока по-прежнему выполняется в цикле консенсуса, когда блок применяется. Узел, который синхронизируется, повторно проверяет каждый сертификат и каждое доказательство каждого блока, прежде чем принять его; ничто не считается достоверным лишь потому, что его подписал кворум.
Уровни
| уровень | бюджет циклов (2ᵗ − 1) | строки cpu | где используется |
|---|---|---|---|
| 10 | 1 023 | 2¹⁰ | гость авторизации; private_payment, fib |
| 12 | 4 095 | 2¹² | |
| 14 | 16 383 | 2¹⁴ | гость пакета скрытого актива (и выведенный из обращения гость bundle); крупнейший вызов |
| 16 | 65 535 | 2¹⁶ | доказательство вызова EVM в тестовом наборе; транслированный ERC-20 approve (вызван в цепочке 13) |
| 18 | 262 143 | 2¹⁸ | ERC-20 transfer и transferFrom, транслированные или интерпретируемые |
| 20 | 1 048 575 | 2²⁰ | SPL Token, транслированный или на госте интерпретатора sBPF |
Начиная с fullnode v0.5.6 (2026-09-25) доказательство вызова выше уровня 14 отклоняется (CallTierTooHigh) до построения ключа верификатора, а блок, несущий такое доказательство, недействителен; вызов может также содержать не более 128 перестановок Keccak-f и 128 сжатий SHA-256. Уровни с 16 по 20 по-прежнему доказываются, но только вне цепочки: ни одну из строк выше них нельзя вызвать в цепочке 21, а цепочка 21, как и цепочки 19 и 20, отклоняет развёртывание программы, слишком большой для любого вызова уровня 14, — более 8 180 слов без публичного входа (ProgramUncallable) (бюджет).
Доказывающий выбирает наименьший уровень, бюджет которого покрывает циклы плюс строки дайджеста программы и входа; прогон, не укладывающийся ни в один, завершается ошибкой до доказательства. Публичен только уровень. Каждый шаг примерно вчетверо увеличивает время доказательства и немного добавляет к размеру доказательства. С цепочки 20 комиссия вызова следует лимиту газа, объявленному его доказательством, и размеру в байтах, а не уровню; в цепочке 21 этот минимум сжигается, а не выплачивается предлагающему блок (Комиссии).
Наборы ограничений и хардфорки
Набор ограничений — это точный набор таблиц, столбцов, шин, публичных значений и параметров FRI, которые проверяет верификатор. Доказательство, созданное при одном наборе, не проходит проверку при другом, ни в одном из направлений, а стартовый повтор узла заново проверяет каждое доказательство в своей цепочке, так что узел, собранный с другим набором, падает на первом же доказательстве и усекает цепочку. Поэтому каждое изменение набора выпускается как новый идентификатор цепочки с одной сборкой на всех узлах, и поэтому rand_status сообщает hc_bundle и hc_auth, а узел, чья сборка не совпадает с genesis, отказывается запускаться.
| набор | дата | что изменилось |
|---|---|---|
| 2 | 2026-09-10 | пять исправлений корректности (soundness) после первой проверки |
| 3 | 2026-09-11 | чип Poseidon2, hc внутри схемы, таблица программы как свидетель, подсловная память, RV32M, FRI перенастроен на 27 запросов |
| 4 | 2026-09-11 | входное обязательство с солью H_IN с отдельной таблицей; загрузчик плоского бинарного файла |
| 5 | 2026-09-12 | необязательная таблица keccak; высота памяти, объявляемая доказательством; два критических исправления по итогам аудита zk; FRI снова на 80 запросов; MAX_PROOF_BYTES увеличен до 2 MiB |
| 6 | 2026-09-14 | обязательная таблица public и H_PUB; необязательная таблица sha256; интерпретаторы EVM и sBPF в виде гостевых библиотек; 34 публичных значения. Эти наборы использовали цепочки с 12 по 15. |
| 7 | 2026-09-28 | каждый терминал LogUp ослеплён через шину BLIND; каждая объявленная таблица ограничена снизу 2⁷ строками; 32-битные проверки диапазона для входных, публичных слов и слов соли; системный вызов POSEIDON2_LEN (7); JALR обнуляет бит 0 своей цели и требует funct3 = 0; ключи верификатора солятся из key_derivation_v2. Эти наборы использовали цепочки 16 и 17. |
| 8 | 2026-09-29 | счётчик газа: столбец GAS в таблице cpu и публичное значение GAS_LIMIT; 35 публичных значений. Эти наборы использовали цепочки с 18 по 20. |
| 9 | 2026-10-12 | чип MODQ: системный вызов 8 (MODQ, одно NTT по модулю q, обратное NTT, скалярное произведение или умножение с вычитанием над многочленами с 256 коэффициентами, q = 8,380,417 из Dilithium) и необязательная таблица modq, которую доказательство объявляет в новом поле заголовка modq_log_height; таблица cpu получила столбцы этого системного вызова, поэтому изменились все ключи верификатора и кодировка доказательства; фаза 4 rVM: деревья Меркла (Merkle spans) в машине рекурсии. Таблицу несёт только гостевая программа аутентификации мультиподписи. Что запускает цепочка 21. |
Цепочки 14 и 15 не изменили ни одного ограничения. Узел цепочки 15 хранит 86 раундовых констант Poseidon2 как литеральную таблицу вместо детерминированной выборки из затравки (аудит ZKV-2): значения те же, поэтому ни хеш, ни дайджест, ни доказательство не изменились. Цепочка 14: пакет скрытых активов (hidden-asset bundle) — новая гостевая программа (новый hc_bundle), а привязка транзакции использует публичный сегмент, который набор 6 уже привязывает внутри схемы. Это тем не менее хардфорк: изменились формат пакета в сети, зафиксированная гостевая программа и каждый идентификатор транзакции, новая сборка отклоняет транзакцию цепочки 13 с пакетом, а кошелёк, собранный до форка, выдаёт доказательства с пустым сегментом, которые цепочка отклоняет.
Каждая из последующих цепочек меняла то, чем является доказательство. Цепочка 16 (fullnode v0.6.1, 2026-09-28) перешла на набор ограничений 7, зафиксировала безветвящуюся гостевую программу пакета v2 и набор hardening_v6 после того, как проверка 2026-09-27 показала, что короткие таблицы и неослеплённые терминалы LogUp раскрывали закрытые данные (Как работает zkVM). Изменились все ключи верификатора. Цепочка 17 (v0.6.3, 2026-09-29) сохранила набор 7 и добавила раздельную авторизацию: гостевую программу пакета v3, гостевую программу аутентификации, два новых поля в сетевом формате пакета и домен идентификатора транзакции rand-txid-3. Цепочка 18 (v0.6.7-rc1, 2026-09-29) перешла на набор ограничений 8 ради счётчика газа. Измеренная стоимость в размере доказательства — менее 1%. Цепочка 19 (2026-10-01) — повторный genesis цепочки 18 на той же сборке v0.6.7, в доказательствах она ничего не изменила. Цепочка 20 (fullnode v0.6.8, 2026-10-01) сохранила набор ограничений 8, те же гостевые программы и ключи верификатора и изменила то, к чему привязано доказательство: привязки транзакции и вызова несут хеш genesis (binding_domain: 1) — публичный вход, который вычисляют кошелёк и реестр, так что ни одна схема не изменилась. Это тем не менее был хардфорк, поскольку доказательства кошелька v0.6.7 на ней не проходят проверку. Цепочка 21 (fullnode v0.8.0, 2026-10-12) перешла на набор ограничений 9 ради приватной мультиподписи: проверка Dilithium2 — это в основном полиномиальная арифметика по модулю q, 880 102 цикла в инструкциях RV32 и 80 572 с системным вызовом MODQ, что позволяет гостевой программе аутентификации мультиподписи (hc_auth_multisig, 9705f8e2…8247, уровень 18) проверять до трёх подписей в пределах 262 143 циклов уровня 18. Гостевые программы пакета и аутентификации с одним ключом сохраняют свои дайджесты, изменились все ключи верификатора и кодировка доказательства, а сборка v0.8.0 при запуске отклоняет цепочки с 18 по 20; доказательство от более старого кошелька не декодируется на цепочке 21. Каждая сборка отклоняет предшествующие ей цепочки по хешу genesis.
Две заметки аудита, которые содержатся в коде и заслуживают внимания: публичное значение TIER проверяется верификатором по заголовку доказательства и по битам степени пакета, но самой схемой не ограничивается (аудит ZL1: отмечено для следующего набора, а не исправлено, поскольку его удаление сдвигает раскладку публичных значений); а H_IN — обязательство, видимое гостевой программе, которое верификатор не сравнивает со значением, переданным вызывающей стороной, — так задумано.
Предстоящее: агрегация блоков
При примерно 1,43 MB на доказательство пакета скрытых активов в цепочках 14 и 15 блок в 4 MiB (по умолчанию и в цепочке 12) вмещал два экранированных перевода; при ~1,3 MB для пакета 2-in-2-out — три. Цепочки 13, 14 и 15 подняли предел блока до 20 MiB (max_block_bytes), что даёт место для четырнадцати. Цепочка 20 сохранила 20 MiB, а перевод в ней нёс около 2,87 MB доказательства, так что блок вмещал около семи; цепочка 21 устанавливает 19 MiB (19 922 944 байта, три доказательства по 6 MiB и один мебибайт), что вмещает около шести. Решение, которое fullnode выбрал (2026-09-12) вместо обрезки истории и вместо увеличения блока, — агрегация на уровне блока: одно рекурсивное доказательство на каждое запечатанное окно, проверяющее N доказательств пакетов, так что история остаётся доказательно подтверждённой от начала до конца, а исходные доказательства можно отбросить. Она реализована и влита, но не активирована, а начиная с цепочки 14 её необходимо измерить заново, прежде чем активировать: допускаемая форма пакета измерялась с пустым публичным сегментом (public 2), тогда как пакет, привязанный к транзакции, объявляет public 4, поэтому ни один пакет, доказанный на цепочке 14, ей не соответствует. Наборы ограничений 7 и 8 снова сдвинули форму: доказательство пакета теперь объявляет public 7 и публикует 35 значений, так что интерфейс агрегата — 35 слов на доказательство. Сборка узла отказывается запускаться на любом genesis, содержащем раздел aggregation, а цепочки с 14 по 20 были созданы без него. Genesis с динамическими ценами на газ, как у цепочки 20, также отклоняется при наличии раздела aggregation. Начиная с fullnode v0.5.8 доказательство агрегата также привязывает своего агрегатора (аудит AGG-2: программа поглощает aggregate_binding(chain_id, aggregator, nonce)), поэтому дайджест программы допускаемой формы нужно измерять на сборке, содержащей это изменение. Активация также всё ещё ждёт сквозной проверки подделки агрегата против исправленного верификатора рекурсии, которая не проводилась, и решения по доказательству аутентификации: программа агрегата проверяет только доказательства пакетов, поэтому в цепочке с раздельной авторизацией запечатывание окна уменьшило бы перевод примерно с 2,87 MB до примерно 1,37 MB, а не до нуля.
Что реализовано:
- вторая, нативная для Goldilocks машина (VM рекурсии,
randprotocol-rvm), чья программа-верификатор проверяет доказательство RV32 примерно за 1,97 миллиона строк на уровне 21 (2 044 506 при наборе ограничений 7), и N-обобщённая программа агрегата над окном доказательств пакетов; - две роли: валидаторы остаются дёшевыми для CPU и проверяют один агрегат на каждый запечатанный блок; агрегаторы (беспермиссионный реестр с залогом и экранированным адресом выплат) доказывают агрегаты на машинах уровня GPU и получают долю за доказательство покрытых пакетов плюс субсидию блока в новых RAND по графику с халвингом;
- пять действий (
RegisterAggregator,UnbondAggregator,WithdrawAggregator,SlashAggregator,Aggregate;SlashAggregatorостаётся в сетевом формате и отклоняется, потому что повторно отправленный агрегат переподписывает тот же nonce и не является equivocation), девятишаговый приём, запечатывание и обрезка покрытых пакетов до примерно 3 KB публичных полей на каждый, синхронизация в запечатанной форме, обходящаяся свежему узлу в одну проверку рекурсии на окно, методы RPCrand_getAggregate,rand_getAggregators,rand_getUnsealed,rand_getRawTransactionи демонrand-node aggregate --watch.
Измерено на тестовом профиле FRI: один агрегат с N=1 доказан примерно за 26 минут на загруженном ноутбуке (327 035 байт); свежий узел применил запечатанный пакет из семи блоков меньше чем за секунду с одной проверкой рекурсии. Классы машин в первоначальной оценке: N=1 требует ≥ 64 GB памяти хоста, N=2 ≥ 128 GB, N=3 ≥ 160 GB; промышленный N ≥ 2 относится к бэкенду CUDA, для которого нужен GPU-узел, которого пока не существует. Измерено на машине с 256 GB при наборе ограничений 7 (2026-09-28 и 29): агрегат N=2 занял 133 GB, N=3 — 221 GB, а доказательство выхода в промышленном варианте (программа-верификатор над одним внутренним доказательством) превысило 256 GB. Ничего из этого не измерялось заново при наборах ограничений 8 и 9. Пока агрегация не активирована, ни один агрегат не заменяет доказательство на цепочке 21 (чей genesis, как и у цепочки 20, не содержит раздела aggregation): два её архивных узла хранят каждое исходное доказательство, а её валидаторы обрезают историю старше 24 часов.