Użyj tej strony, aby dobrać rozmiar maszyny dowodzącej, zrozumieć, dlaczego transfer trwa ponad minutę i dlaczego przepustowość ogranicza miejsce w bloku, a nie moc obliczeniowa, oraz wiedzieć, co się psuje, gdy zmienia się system dowodowy. Wszystko, co przyjmuje walidator, jest poparte dowodem, który sam zweryfikował.
Co stwierdza dowód
Jedna relacja, dla każdego programu uruchamianego przez łańcuch:
Ten program RV32IM, uruchomiony od
base_pc, na prywatnym wektorze wejściowym zatwierdzonym przezH_INi publicznym segmencie wejściowym zatwierdzonym przezH_PUB, zatrzymał się w ciągu2ᵗ − 1cykli, zużył co najwyżejGAS_LIMITgazu i opublikował te osiem słów wyjściowych.
Program jest identyfikowany przez swój skrót wewnątrz obwodu hc; weryfikator nigdy nie widzi żadnego słowa instrukcji. Transfer osłonięty to ta relacja zastosowana do gościa pakietu z ukrytym aktywem (hidden-asset bundle guest), ręcznie złożonego programu 4-wejścia-4-wyjścia, którego hc jest przypięty w pliku genesis jako hc_bundle. Chain 20 przypina gościa v3 (guests::bundle_hidden_v3, 60af094a…6e3fce, od chain 17). Chain 14 i 15 przypinały v1 (83d3a370…cd0ef8), a chain 16 wersję v2 bez rozgałęzień (651043e2…839b). Od chain 17 każdy pakiet niesie także drugi dowód, dla gościa uwierzytelniania (guests::auth, genesis hc_auth, 1e4e347f…5639c1): dowód pakietu przyjmuje klucz podglądu, a dowód uwierzytelniania wykazuje, że nadawca posiada stojący za nim klucz wydatkowania. To podzielona autoryzacja i dzięki niej sparowany prover, który ma tylko klucz podglądu, może wykonać dowód pakietu. Gość z ukrytym aktywem zastąpił gościa bundle 2-wejścia-2-wyjścia z chainów do 13, który pozostaje w fullnode tylko na potrzeby testów i którego żaden chain nie przypina. Poufne wywołanie to ta sama relacja zastosowana do wdrożonego programu (Programs).
Jak portfel dowodzi pakiet
rand send <rand1…> <amount> wykonuje prywatną pracę lokalnie, a do łańcucha trafiają wyłącznie dowody, zobowiązania, nullifiery i zapieczętowane koperty:
- Przeskanuj drzewo kluczem podglądu i wybierz wejścia: co najwyżej dwie notatki RAND pokrywające kwotę wraz z opłatą w slotach 2–3, a przy transferze lub spaleniu tokena co najwyżej dwie notatki tokena w slotach 0–1, przy czym notatki RAND pokrywają samą opłatę. Nieużywany slot wejściowy to atrapa: kwota 0, należy do portfela, jej niepowodzenie członkostwa jest maskowane w obwodzie, a nullifier mimo to jest publikowany. Od gościa v2 gość jest pozbawiony rozgałęzień: ścieżka atrapy jest haszowana przez wszystkie 32 poziomy tak samo jak ścieżka prawdziwej notatki.
- Pobierz kotwicę głowy (
rand_getAnchor) oraz 32-poziomowe świadectwo Merkle’a każdego prawdziwego wejścia (rand_getWitness(index)), sprawdzając zwrócony korzeń względem kotwicy. - Zbuduj cztery wyjścia: notatkę odbiorcy i notatkę reszty w grupie, która przenosi wartość, obecne nawet przy zerze, oraz atrapy o kwocie zero w pozostałych slotach, zapieczętowane tymczasowym kluczem.
- Zapieczętuj każde wyjście w kopercie (ML-KEM-768 do odbiorcy oraz klucz transakcji opakowany pod
ovkportfela), złóż całą transakcję wraz z jej akcją i wyznacz jej powiązanie (binding):blake3("rand-tx-bind-1" || …)z transakcji z wyczyszczonymi dowodami, osiem słów (Transactions). Na chain 20, której genesis ustawiabinding_domain: 1, jest toblake3("rand-tx-bind-2" || …)z hashem genesis na początku, a następnie identyfikatorem chaina, więc dowód wykonany dla jednego chaina nie przejdzie weryfikacji na żadnym innym, nawet o tym samym identyfikatorze. Portfel starszy niż v0.6.8 używa starego powiązania, a chain 20 odrzuca jego dowody. - Autoryzuj: wylosuj świeżą 256-bitową sól i udowodnij gościa uwierzytelniania na jego 16-słowowym prywatnym wejściu, kluczu wydatkowania i soli, z powiązaniem jako publicznym segmentem wejściowym, na tierze 10. Wyprowadza
nkz klucza wydatkowania i publikujec = H(AUTH, nk ‖ salt), które pakiet niesie jakoauth_commit. - Udowodnij gościa pakietu na jego 1212-słowowym prywatnym wejściu (klucz podglądu
nk, cztery sloty wejściowe z ich ścieżkami, kotwica, cztery wyjścia,fee,burn_a,burn_r, prywatne aktywoA,time, sól) z tym samym powiązaniem jako publicznym segmentem wejściowym, na tierze 14. Dowód wykazuje własność, członkostwo, to, że każde prawdziwe wejście niesie aktywo swojego slotu, cztery nullifiery, to samocoraz dwa bilansein₀ + in₁ = out₀ + out₁ + burn_aiin₂ + in₃ = out₂ + out₃ + fee + burn_r. To dowód, który sparowany prover może wykonać zamiast portfela; dowód uwierzytelniania powstaje na maszynie samego portfela. - Sprawdź opublikowany skrót dowodu względem skrótu obliczonego z jawnego tekstu i prześlij
Transaction { chain_id, bundle, action: None }.
Kolejność ma znaczenie od chain 14: koperty i akcja istnieją przed dowodami, ponieważ dowody się do nich zobowiązują. W przypadku wywołania najpierw powstaje dowód wywołania, który również wchodzi w skład powiązania. Na chainie z hardening_v6 dowód wywołania jest sam wykonywany nad powiązaniem wywołania, czyli transakcją z wyczyszczonymi oboma dowodami (rand-call-bind-1 na chainach od 16 do 19, rand-call-bind-2 z hashem genesis na chain 20), które obejmuje nullifiery pakietu opłaty, więc nie można go skopiować pod inny pakiet.
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
Transkrypt to format wyjścia portfela z przewodnika fullnode według stanu na chain 14; pokazana liczba bajtów dotyczy dowodu pakietu w profilu produkcyjnym zatwierdzonego na chain 14. Portfel od chain 17, w tym v0.6.8 na chain 20, wypisuje przed tymi dwie linie, proving the spend authorisation on this machine (tier 10; seconds)… oraz authorisation proved in …: tier 10, … bytes, a linię pakietu formułuje jako proving the bundle (tier 14; about a minute and a half on a laptop)….
Ta sama maszyneria opłaca każdą akcję, zawsze z dokładnie jednym pakietem: wdrożenie, wywołanie, rejestracja tokena lub emisja tokena jadą na samotransferze RAND o zerowej wartości, bond na pakiecie, który spala stawkę przez burn_r, a spalenie tokena lub spalenie mostu na jednym pakiecie, który spala aktywo ze slotów 0–1 (burn_a, burn_asset) i płaci opłatę w RAND ze slotów 2–3. Aktywo przenoszone przez transfer jest słowem świadectwa i nie występuje w żadnym polu publicznym.
Ile to kosztuje
Zmierzone na laptopie deweloperskim (Apple Silicon, build release), liczby zapisane w dokumentach samego fullnode:
| gość | słowa | cykle | tier | dowodzenie | rozmiar dowodu (produkcja, 80 zapytań) |
|---|---|---|---|---|---|
| gość pakietu v3 (chainy 17 do 20) | — | 4 024 cykle i zapas 273 permutacji Poseidon2 w budżecie tieru 14 | 14 | ≈ 100 s, szczyt 5,7 GB; od 102,5 do 134,0 s zmierzone na chain 18 (2026-09-30) | ≈ 1,50 MB; od 1 494 151 do 1 504 260 bajtów zmierzone na chain 18 (2026-09-30) |
| gość uwierzytelniania (chainy 17 do 20) | — | 250 | 10 | ≈ 7 s; od 6,6 do 19,9 s zmierzone na chain 18 (2026-09-30) | ≈ 1,37 MB; od 1 364 940 do 1 375 371 bajtów zmierzone na chain 18 (2026-09-30) |
| pakiet z ukrytym aktywem v1, 4-wejścia-4-wyjścia (chainy 14 i 15) | — | poniżej budżetu tieru 14, z zapasem około 2071 cykli (13%) | 14 | ≈ 98–100 s, szczyt 5,7 GB | ≈ 1,43 MB; 1 422 116 i 1 423 170 bajtów zmierzone na chain 14 |
bundle, 2-wejścia-2-wyjścia (wycofany; chainy do 13) | 3 811 | ≈ 9 160 | 14 | ≈ 100 s (94,6–97,9 s osobno; po 114 s każdy przy dwóch naraz) | 1 321 773 bajtów zmierzone na chain 8 |
private_payment (wywołanie) | niewiele | < 1000 | 10 | ≈ 7 s | ≈ 1,37 MB (fib na tierze 10: 1 367 688 bajtów przy zestawie ograniczeń 7; 1 298 729 przy zestawie 6) |
| wywołanie bez tablicy haszy (księga poza łańcuchem, chain 18) | 773 | — | 14 | 114,8 s | 1 498 589 bajtów |
| wywołanie z tablicą SHA-256 (dowód zobowiązań, chain 18) | 994 | — | 14 | 122,9 s | 1 911 152 bajtów |
| wywołanie z tablicą Keccak (anonimowe głosowanie, chain 18) | — | — | 12 | 29,2 s | 3 346 865 bajtów |
Weryfikacja jest kosztem konsensusu, ponoszonym przez każdy węzeł: około 16 ms przy rozgrzanym kluczu weryfikatora, około 230 ms za pierwszym razem, gdy buduje się klucz dla danego kształtu. Klucz weryfikatora nie zależy od zawartości programu — jest indeksowany przez (tier, program_log_height, input_log_height, keccak_log_height, sha256_log_height, public_log_height) — więc węzeł buduje jeden na kształt i używa go ponownie; dla wdrożonego programu klucz jest obliczany raz w tle w chwili wdrożenia (około 2 s na laptopie, 7 s na serwerze z 2 vCPU). Pakiet 2-wejścia-2-wyjścia z chain 13 i wcześniejszych deklarował kształt program 12, input 10, keccak 0, sha256 0, public 2, mem 16; dowód pakietu z chain 14 deklaruje public 4, czyli wysokość ośmiu słów powiązania, nie zawiera żadnej tablicy haszy i jest odrzucany, zanim zbudowany zostanie jakikolwiek klucz weryfikatora, jeśli deklaruje inny tier, którąkolwiek z tablic lub inną wysokość publiczną. Od zestawu ograniczeń 7 każda zadeklarowana tablica ma co najmniej 2⁷ wierszy, więc dowód pakietu z chain 20 deklaruje public 7.
Transfer w łańcuchu 20 niesie zatem około 2,87 MB dowodu: dowód paczki i dowód autoryzacji, a wywołanie dokłada trzeci dowód. Każdy z nich musi mieścić się w genesisowym max_proof_bytes, które w łańcuchu 20 wynosi 4 194 304 (4 MiB), tak jak w łańcuchach od 17 do 19, wobec 8 MiB w łańcuchach od 13 do 16.
Guest ukrytego aktywa mieści się w poziomie 14 tylko dlatego, że wczytuje swoje prywatne wejścia w pętli i scala odczyty sąsiadów w sprawdzeniu Merkle’a; napisana w starszym, rozwiniętym stylu ta sama relacja ląduje na poziomie 16, z czasem około 400 s i 21–22 GB, co wykluczyłoby portfele z 16 GB.
Dowodzenie jest ograniczone przez CPU, a portfel używa dziś na każdej platformie backendu CPU. W uruchomieniach na dużych poziomach prover był jednowątkowy: droplet z 16 vCPU pracował na 99% jednego rdzenia, a o tym, czy dowód się zakończył, decydowała pamięć, nie rdzenie (pamięć dowodzenia). Flaga --cuda w poleceniach send, bond, call, deploy, bridge-mint i bridge-burn wybiera backend NVIDIA, który wymaga kompilacji z --features cuda. Jego kernele po raz pierwszy uruchomiono na prawdziwym sprzęcie, NVIDIA H100, 2026-09-28 i zgodziły się z referencją CPU, ale w checkoucie circuits, który wydanie wendoruje, nie ma zatwierdzonego PTX, więc kompilacja kończy się błędem no PTX for the GPU kernels, dopóki kernele nie zostaną skompilowane. Żadnego produkcyjnego dowodu nie zmierzono na węźle floty z GPU. Celowo nie ma awaryjnego przejścia na CPU. Wywołanie CUDA nie może też zapieczętować koperty wejścia, ponieważ sól nigdy nie opuszcza provera. Szczytowe zużycie pamięci dla dowodu paczki ukrytego aktywa na poziomie 14 to około 5,7 GB (Production FRI, CPU); większe klasy pamięci dotyczą dowodów interpretera i rekursji poniżej (≥ 64 GB i więcej).
Jak węzeł weryfikuje
Przyjęcie transakcji najpierw wykonuje tanie kontrole (Transakcje), a następnie:
- przelicza skrót paczki (bundle digest) z opublikowanego jawnego tekstu (kotwica, cztery nullifikatory, cztery zobowiązania,
fee,burn_a,burn_r,burn_asset,time,auth_commitpaczki oraz słowo skażenia ustalone na zero) i wymaga, by równał się temu, co opublikował dowód — dowód, którego świadek złamał relację, publikuje skażony skrót, który nie pasuje do żadnego jawnego tekstu. Niektóre kontrole są natomiast strukturalne (guest sam dostarcza nadawcę, aktywo i czas wyjścia, więc prover nie może ich wybrać), a prywatnego aktywa nie ma w skrócie; - dekoduje dowód i sprawdza zadeklarowane wysokości względem poziomu (
check_declared_heights), tak aby granica kształtu dowodu w łańcuchu była granicą weryfikatora. Zanim sprawdzony zostanie jakikolwiek podpis lub dowód, na każdej przesłanej lub rozgłoszonej transakcji (a przyhardening_v6także w walidacji bloku) działa kanoniczny filtr dowodów; od fullnode v0.6.8 (audyt v6, ZKV-4) filtr ten najpierw ogranicza każdy zadeklarowany stopień do 25 bitów (MAX_HONEST_DEGREE_BITS, czyli sufit tabeli pamięci plus jeden), więc nagłówek z ogromnym stopniem nie zatrzymuje już węzła, gdy dla niego wyprowadzany jest uczciwy harmonogram składania, a panika wewnątrz filtra odrzuca tę transakcję zamiast zatrzymywać węzeł; - oblicza wiązanie (binding) transakcji i uruchamia
Machine::verify_public(hc_bundle, &binding, proof)— weryfikator wsadowy oraz sprawdzenie, żeH_PUBjest skrótem tych ośmiu słów, więc dowód skopiowany na transakcję z inną akcją, inną kopertą lub innym identyfikatorem łańcucha, a w łańcuchu 20 na genesis innego łańcucha, nie przechodzi weryfikacji (do łańcucha 13 włącznie segment był pusty i nic nie wiązało dowodu z jego transakcją); - weryfikuje dowód autoryzacji względem
hc_authi tego samego wiązania oraz wymaga, by opublikowane przez niegocrównało sięauth_commit. Paczka bez dowodu autoryzacji jest odrzucana (AuthMissing), podobnie jak ta, którejcsię różni (AuthMismatch); - wymaga, by
GAS_LIMITdowodu paczki równał się genesisowemubundle_gas_limit, czyli 20 479, a dowodu autoryzacji 1 279, czyli sufitom nagłówków obu guestów (BundleGasLimit,AuthGasLimit); - dla wywołania robi to samo względem zapisanego
code_hashprogramu, z publicznymi słowami programu, po których następuje wiązanie wywołania jako segment (Invokew RPL-2 dołącza swoje przejście jako słowa kontekstu, Programy), a następnie sprawdza opłatę względem limitu gazu deklarowanego przez dowód i jego rozmiaru w bajtach (Opłaty).
Transakcja przesłana przez RPC lub gossip jest weryfikowana na jednym z czterech workerów za kolejką o głębokości 64, poza pętlą konsensusu, i rozgłaszana dalej dopiero po weryfikacji; kubełek tokenów (token bucket) na peera (burst 16, uzupełnianie 4 na sekundę) ogranicza to, co peer może zmusić węzeł do zweryfikowania, a pamięć podręczna na 8 192 wpisy odpowiada za darmo na powtórzenie transakcji odrzuconej na stałe. Weryfikacja dowodów wewnątrz proponowanego bloku nadal działa w pętli konsensusu, gdy blok jest stosowany. Węzeł, który się synchronizuje, ponownie weryfikuje każdy certyfikat i każdy dowód każdego bloku, zanim go zaakceptuje; niczemu nie ufa się dlatego, że podpisał to kworum.
Poziomy
| poziom | budżet cykli (2ᵗ − 1) | wiersze cpu | używany przez |
|---|---|---|---|
| 10 | 1 023 | 2¹⁰ | guest autoryzacji; private_payment, fib |
| 12 | 4 095 | 2¹² | |
| 14 | 16 383 | 2¹⁴ | guest paczki ukrytego aktywa (oraz wycofany guest bundle); największe wywołanie |
| 16 | 65 535 | 2¹⁶ | dowód wywołania EVM w zestawie testów; przetłumaczone approve ERC-20 (wywołane w łańcuchu 13) |
| 18 | 262 143 | 2¹⁸ | transfer i transferFrom ERC-20, przetłumaczone lub interpretowane |
| 20 | 1 048 575 | 2²⁰ | SPL Token, przetłumaczony lub na guestcie interpretera sBPF |
Od fullnode v0.5.6 (2026-09-25) dowód wywołania powyżej poziomu 14 jest odrzucany (CallTierTooHigh) przed zbudowaniem klucza weryfikatora, a blok, który taki niesie, jest nieważny; wywołanie może ponadto zawierać co najwyżej 128 permutacji Keccak-f i 128 kompresji SHA-256. Poziomy od 16 do 20 nadal dają się dowodzić, ale tylko poza łańcuchem: żadnego z wierszy powyżej nie można wywołać w łańcuchu 20, a łańcuch 20 odrzuca wdrożenie programu zbyt dużego dla jakiegokolwiek wywołania na poziomie 14, czyli ponad 8 180 słów bez publicznego wejścia (ProgramUncallable) (budżet).
Prover wybiera najmniejszy poziom, którego budżet pokrywa cykle oraz wiersze skrótu programu i wejścia; uruchomienie, które się nie mieści, kończy się niepowodzeniem przed dowodzeniem. Publiczny jest tylko poziom. Każdy krok mniej więcej czterokrotnie wydłuża czas dowodzenia i nieco zwiększa rozmiar dowodu. W łańcuchu 20 opłata za wywołanie zależy od limitu gazu deklarowanego przez jego dowód i od jego rozmiaru w bajtach, nie od poziomu (Opłaty).
Zestawy ograniczeń i hard forki
Zestaw ograniczeń (constraint set) to dokładny zbiór tabel, kolumn, szyn, wartości publicznych i parametrów FRI, które sprawdza weryfikator. Dowód wykonany w jednym zestawie nie przechodzi weryfikacji w innym, w żadnym kierunku, a startowe odtworzenie węzła ponownie weryfikuje każdy dowód w jego łańcuchu — więc węzeł zbudowany z innego zestawu zawodzi na pierwszym dowodzie i ucina łańcuch. Dlatego każda zmiana zestawu jest wydawana jako nowy identyfikator łańcucha z każdym węzłem na jednym buildzie i dlatego rand_status zgłasza hc_bundle i hc_auth, a węzeł, którego build nie zgadza się z genesis, odmawia startu.
| zestaw | data | co się zmieniło |
|---|---|---|
| 2 | 2026-09-10 | pięć poprawek poprawności (soundness) po pierwszym przeglądzie |
| 3 | 2026-09-11 | układ Poseidon2, hc w obwodzie, tabela programu jako świadek, pamięć poniżej słowa, RV32M, FRI przestrojone na 27 zapytań |
| 4 | 2026-09-11 | solone zobowiązanie wejścia H_IN z własną tabelą; loader płaskich binariów |
| 5 | 2026-09-12 | opcjonalna tabela keccak; wysokość pamięci deklarowana przez dowód; dwie krytyczne poprawki z audytu zk; FRI z powrotem na 80 zapytań; MAX_PROOF_BYTES do 2 MiB |
| 6 | 2026-09-14 | obowiązkowa tabela public i H_PUB; opcjonalna tabela sha256; guesty interpretera EVM i sBPF jako biblioteki; 34 wartości publiczne. To, co uruchamiały łańcuchy od 12 do 15. |
| 7 | 2026-09-28 | każdy terminal LogUp zaślepiony przez szynę BLIND; każda zadeklarowana tabela ma dolny próg 2⁷ wierszy; 32-bitowe sprawdzenia zakresu na słowach wejścia, publicznych i soli; syscall POSEIDON2_LEN (7); JALR zeruje bit 0 swojego celu i wymaga funct3 = 0; klucze weryfikatora solone z key_derivation_v2. To, co uruchamiały łańcuchy 16 i 17. |
| 8 | 2026-09-29 | licznik gazu: kolumna GAS w tabeli cpu i wartość publiczna GAS_LIMIT; 35 wartości publicznych. To, co uruchamiają łańcuchy od 18 do 20. |
Łańcuchy 14 i 15 nie zmieniły żadnego ograniczenia. Węzeł łańcucha 15 trzyma 86 stałych rundowych Poseidon2 jako literalną tabelę zamiast losowania z ziarna (audyt ZKV-2) — te same wartości, więc żaden skrót, digest ani dowód się nie przesunął. Łańcuch 14: paczka ukrytego aktywa jest nowym guestem (nowe hc_bundle), a wiązanie transakcji używa segmentu publicznego, który zestaw 6 już wiąże w obwodzie. Mimo to jest to hard fork — zmienił się format przesyłania paczki, przypięty guest i każdy identyfikator transakcji, transakcja łańcucha 13 niosąca paczkę jest odrzucana przez nowy build, a portfel zbudowany przed forkiem produkuje dowody z pustym segmentem, które łańcuch odrzuca.
Trzy kolejne łańcuchy zmieniły to, czym jest dowód. Chain 16 (fullnode v0.6.1, 2026-09-28) przeszedł na zestaw ograniczeń 7, przypiął bezgałęziowego guesta bundle v2 i ustawił hardening_v6, gdy przegląd z 2026-09-27 wykazał, że krótkie tabele i nieoślepione terminale LogUp ujawniały dane prywatne (How the zkVM works). Zmieniły się wszystkie klucze weryfikacyjne. Chain 17 (v0.6.3, 2026-09-29) zachował zestaw 7 i dodał rozdzielone autoryzowanie: guest bundle v3, guest auth, dwa nowe pola w formacie przesyłowym bundle oraz domenę identyfikatora transakcji rand-txid-3. Chain 18 (v0.6.7-rc1, 2026-09-29) przeszedł na zestaw ograniczeń 8 z powodu licznika gazu. Jego zmierzony koszt w rozmiarze dowodu wynosi poniżej 1%. Chain 19 (2026-10-01) to ponowny genesis chain 18 na tym samym buildzie v0.6.7, który niczego nie zmienił w dowodach. Chain 20 (fullnode v0.6.8, 2026-10-01) zachowuje zestaw ograniczeń 8 oraz te same guesty i klucze weryfikacyjne, a zmienia to, z czym dowód jest powiązany: powiązania transakcji i wywołań zawierają hash genesis (binding_domain: 1), czyli publiczne wejście, które obliczają portfel i księga, więc żaden obwód się nie zmienił. Mimo to jest to hard fork, ponieważ dowody z portfela v0.6.7 nie przechodzą na nim weryfikacji. Każdy build odrzuca wcześniejsze łańcuchy na podstawie hasha genesis.
Dwie uwagi z audytu, zawarte w kodzie i warte poznania: wartość publiczną TIER weryfikator sprawdza względem nagłówka dowodu i bitów stopnia partii, ale sam obwód jej nie wymusza (audyt ZL1, oznaczony do kolejnego zestawu zamiast poprawiony, ponieważ jej usunięcie przesuwa układ wartości publicznych); natomiast H_IN jest zobowiązaniem widocznym dla guesta, którego weryfikator z założenia nie porównuje z wartością dostarczoną przez wywołującego.
Upcoming: block aggregation
Przy około 1,43 MB na dowód bundle z ukrytym aktywem w chain 14 i 15 blok o rozmiarze 4 MiB (domyślnym, a zarazem tym z chain 12) mieścił dwa transfery shielded; przy dowodzie bundle 2-in-2-out o rozmiarze ~1,3 MB mieścił trzy. Chain 13, 14 i 15 podniosły limit bloku do 20 MiB (max_block_bytes), co daje miejsce na czternaście. Chain 20 zachowuje 20 MiB, a transfer niesie tam około 2,87 MB dowodu, więc blok mieści około siedmiu. Rozwiązanie, które fullnode wybrał (2026-09-12) zamiast przycinania i zamiast większego bloku, to agregacja na poziomie bloku: jeden dowód rekurencyjny na zamknięte okno, który weryfikuje N dowodów bundle, dzięki czemu historia pozostaje od początku do końca opatrzona dowodami, a surowe dowody można usunąć. Jest ona zbudowana i scalona, lecz nieaktywowana, a od chain 14 musi zostać ponownie zmierzona, zanim będzie można ją aktywować: jej dopuszczony kształt bundle zmierzono z pustym segmentem publicznym (public 2), a bundle powiązany z transakcją deklaruje public 4, więc żaden bundle udowodniony w chain 14 do niego nie pasuje. Zestawy ograniczeń 7 i 8 przesunęły ten kształt ponownie: dowód bundle deklaruje teraz public 7 i publikuje 35 wartości, zatem interfejs agregatu to 35 słów na dowód. Build węzła odmawia uruchomienia na każdym genesis zawierającym sekcję aggregation, a chain 14 do 20 zostały utworzone bez niej. Genesis z dynamicznymi cenami gazu, taki jak w chain 20, jest również odrzucany obok sekcji aggregation. Od fullnode v0.5.8 dowód agregatu wiąże także swojego agregatora (audyt AGG-2: program absorbuje aggregate_binding(chain_id, aggregator, nonce)), więc skrót programu dopuszczonego kształtu trzeba zmierzyć na buildzie zawierającym tę zmianę. Aktywacja czeka też nadal na kompleksowe ćwiczenie ze sfałszowanym agregatem wobec naprawionego weryfikatora rekurencji, którego jeszcze nie przeprowadzono, oraz na decyzję w sprawie dowodu auth: program agregatu weryfikuje wyłącznie dowody bundle, więc w łańcuchu z rozdzielonym autoryzowaniem zamknięcie okna zmniejszyłoby transfer z około 2,87 MB do około 1,37 MB, a nie do zera.
Co zostało zbudowane:
- druga maszyna natywna dla Goldilocks (maszyna rekurencji, recursion VM,
randprotocol-rvm), której program weryfikatora sprawdza dowód RV32 w około 1,97 mln wierszy na tierze 21 (2 044 506 w zestawie ograniczeń 7), oraz ogólny względem N program agregatu dla okna dowodów bundle; - dwie role: validatorzy pozostają tani dla CPU i weryfikują jeden agregat na zamknięty blok; agregatorzy (bezzezwoleniowy rejestr z depozytem i osłoniętym adresem wypłat) generują dowody agregatów na maszynach klasy GPU, a wynagrodzeniem jest dla nich udział w koszcie dowodzenia objętych bundle oraz subsydium blokowe w nowych RAND według harmonogramu z połowieniem;
- pięć akcji (
RegisterAggregator,UnbondAggregator,WithdrawAggregator,SlashAggregator,Aggregate;SlashAggregatorpozostaje w formacie przesyłowym i jest odrzucana, ponieważ ponowiony agregat podpisuje ten sam nonce ponownie i nie jest ekwiwokacją), dziewięcioetapowe dopuszczenie, zamykanie i przycinanie objętych bundle do około 3 KB pól publicznych każdy, synchronizacja w formie zamkniętej, która kosztuje nowy węzeł jedną weryfikację rekurencji na okno, metody RPCrand_getAggregate,rand_getAggregators,rand_getUnsealed,rand_getRawTransactionoraz demonrand-node aggregate --watch.
Zmierzone na testowym profilu FRI: jeden agregat N=1 udowodniono w około 26 minut na obciążonym laptopie (327 035 bajtów); nowy węzeł zastosował siedmioblokową partię w formie zamkniętej w mniej niż sekundę, z jedną weryfikacją rekurencji. Klasy maszyn w pierwszym ujęciu: N=1 wymaga ≥ 64 GB pamięci hosta, N=2 ≥ 128 GB, N=3 ≥ 160 GB; produkcyjne N ≥ 2 należy do backendu CUDA, który wymaga węzła GPU, jeszcze nieistniejącego. Zmierzone na maszynie 256 GB w zestawie ograniczeń 7 (2026-09-28 i 29): agregat N=2 zajął 133 GB, N=3 zajął 221 GB, a produkcyjny dowód wyjścia (program weryfikatora nad jednym dowodem wewnętrznym) przekroczył 256 GB. Nic z tego nie zostało ponownie zmierzone w zestawie ograniczeń 8. Dopóki agregacja nie zostanie aktywowana, żaden agregat nie zastępuje dowodu w chain 20: jego dwa węzły archiwalne zachowują każdy surowy dowód, a jego validatorzy przycinają historię starszą niż 24 godziny.