Prawdopodobnie najważniejsze wydarzenie w historii Ethereum, The Merge, miało miejsce 15 września 2022 r. Oznaczało przejście sieci z do , fundamentalnie zmieniając sposób, w jaki Ethereum osiąga konsensus. Ale dlaczego nazywa się to „ ”, a nie „przejściem”? Proof of Work Proof of Stake The Merge Przed The Merge, Ethereum działało w oparciu o konsensus Proof of Work, mechanizm wymagający od „górników” rozwiązywania złożonych zagadek kryptograficznych w celu walidacji transakcji i tworzenia nowych bloków. PoW jest świetny, ale wiąże się z wieloma ograniczeniami, takimi jak zużycie ogromnej mocy obliczeniowej prowadzące do wysokiego zużycia energii elektrycznej i obaw o środowisko, niska przepustowość transakcji z powodu wolniejszego czasu weryfikacji, a tym samym wyzwanie dla adopcji instytucjonalnej, większe ryzyko centralizacji, ponieważ może się skonsolidować do kilku potężnych podmiotów wydobywczych itp. Te i inne powody były motywacją, która skłoniła Ethereum Foundation, zaledwie trzy lata po powstaniu, do rozpoczęcia budowy nowego konsensusu zwanego Proof of Stake, mającego na celu rozwiązanie większości problemów, z którymi borykał się PoW. 1 grudnia 2020 r. Ethereum uruchomiło pierwszą wersję PoS, nowy łańcuch zwany Beacon chain. Beacon Chain nie przetwarzał transakcji użytkowników. Jego jedynym celem było koordynowanie walidatorów i osiąganie konsensusu za pomocą nowego mechanizmu zwanego Gasper. Transakcje nadal były przetwarzane w głównym łańcuchu Proof of Work, więc oba łańcuchy, główny łańcuch Ethereum i Beacon Chain, działały równolegle. Przez prawie dwa lata te dwa łańcuchy działały niezależnie. Następnie, 15 września 2022 r., oryginalny łańcuch porzucił swój konsensus oparty na wydobyciu i podłączył się bezpośrednio do Beacon Chain. W ten sposób dwa łańcuchy stały się jednym. Dlatego nazywa się to The Merge, a nie Transition. Dziś Ethereum działa jako dwuwarstwowy blockchain. Warstwa konsensusu, która wcześniej była Beacon Chain, obsługuje propozycje bloków, atestacje i finalizację. Warstwa wykonania, oryginalny łańcuch Ethereum, obsługuje przetwarzanie transakcji. Być może słyszeliście o nich jako o Eth2 i Eth1, odpowiednio, ale Ethereum Foundation wycofała tę nazwę, ponieważ sugerowała dwa oddzielne sieci, a nie dwie warstwy jednego systemu. Ten artykuł skupia się na warstwie konsensusu. W szczególności, jak Beacon Chain działa jako maszyna stanowa. Co to jest BeaconState? Aby zrozumieć, jak następują przejścia maszyny stanowej, najpierw musimy zrozumieć, co właściwie zawiera stan w momencie narodzin łańcucha. Stan Beacon Chain jest reprezentowany przez pojedynczy obiekt zwany BeaconState. Zawiera on wszystko, czego warstwa konsensusu potrzebuje do funkcjonowania. Czasami nazywany jest „obiektem Boga”. Sama specyfikacja grupuje pola według przeznaczenia, co jest najjaśniejszym sposobem ich prześledzenia. class BeaconState(Container): genesis_time: uint64 genesis_validators_root: Root slot: Slot fork: Fork latest_block_header: BeaconBlockHeader block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT] eth1_data: Eth1Data eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH] eth1_deposit_index: uint64 validators: List[Validator, VALIDATOR_REGISTRY_LIMIT] balances: List[Gwei, VALIDATOR_REGISTRY_LIMIT] randao_mixes: Vector[Bytes32, EPOCHS_PER_HISTORICAL_VECTOR] slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR] previous_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH] current_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH] justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH] previous_justified_checkpoint: Checkpoint current_justified_checkpoint: Checkpoint finalized_checkpoint: Checkpoint Wersjonowanie: genesis_time: uint64 genesis_validators_root: Root slot: Slot fork: Fork Pierwsze cztery zmienne odpowiadają na pytanie „jaki to łańcuch i gdzie się na nim znajdujemy?”. Te pola zakotwiczają tożsamość łańcucha i mówią każdemu węzłowi, jakich reguł protokołu należy przestrzegać. Czas rozpoczęcia to znacznik czasu Unix, który jest ustawiany na początku łańcucha i nigdy się nie zmienia. Czas rozpoczęcia Beacon Chain to 1606824023, co odpowiada dokładnie 1 grudnia 2020 r. o 12:00:23 UTC. Jeśli kiedykolwiek pobierałeś „block.timestamp” z inteligentnego kontraktu, ta wartość jest obliczana na podstawie tego pola. Root validatora rozpoczęcia, podobnie jak znacznik czasu, został dodany na początku łańcucha. Działa on zasadniczo jako separator domen; miesza się z podpisem walidatora podczas propozycji bloków i atestacji, aby odróżnić Ethereum mainnet od jakiegokolwiek innego łańcucha. Slot to po prostu licznik, który mówi nam, gdzie łańcuch jest w czasie. Zwiększa się co 12 sekund, niezależnie od tego, czy blok został wyprodukowany. Fork to obiekt zawierający trzy pola: poprzednia wersja łańcucha, obecna wersja łańcucha i epoka. Kiedy miała miejsce pierwsza aktualizacja w Beacon Chain, 27 października 2021 r., wersje zmieniły się z Fazy 0 na Altair. Obecna wersja, w momencie pisania tego artykułu, to Fulu, a poprzednia wersja to Electra. Podobnie jak root walidatora, hash wersji jest dodawany do podpisów, aby odróżnić jedną wersję forka od drugiej. Epoka z kolei to zestaw 32 slotów, czyli , czyli około 6,4 minuty. Tutaj mają miejsce kontrole finalizacji, kary za przycinanie, kolejka wyjścia i wszystkie inne fajne rzeczy specyficzne dla konsensusu. Tutaj działa Casper FFG, ostatnia część Gaspera. 12 sek x 32 Historia latest_block_header: BeaconBlockHeader block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT] Ta sekcja odpowiada na pytanie „Co działo się w tym łańcuchu?”. Te zmienne nadają łańcuchowi skondensowaną pamięć o jego przeszłości, pozwalając walidatorom na odwoływanie się i weryfikowanie poprzednich stanów bez przechowywania wszystkiego. Nagłówek najnowszego bloku przechowuje nagłówek ostatnio przetworzonego bloku. Służy do zapobiegania duplikatom bloków, ponieważ przed przetworzeniem nowego bloku łańcuch sprawdza, czy root rodzica bloku odpowiada rootowi najnowszego nagłówka bloku. Pola block roots i state roots to listy, które przechowują odpowiednio poprzednie roote bloków i stany, dopóki nie zostaną wypełnione. W każdym slocie roote są zapisywane do odpowiednich tablic pod indeksem . Pozwala to łańcuchowi na sprawdzenie, jak wyglądał stan w każdym ostatnim slocie w ciągu 27 godzin. Historical root dodaje połączony hash tablic block roots i state roots, gdy zostaną wypełnione. Lista jest nielimitowana, ale rośnie powoli, z tylko jednym wpisem co 27 godzin. slot%8192 Eth1 eth1_data: Eth1Data eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH] eth1_deposit_index: uint64 Przed The Merge, Eth2 (Beacon Chain) musiało śledzić, co dzieje się w Eth1 (łańcuch PoW), zwłaszcza transakcje depozytowe, w których nowi walidatorzy blokowali 32 ETH. Możesz się zastanawiać, dlaczego 32 ETH, które miało być przeznaczone na PoS, zostało zablokowane w łańcuchu PoW, a nie w Beacon Chain. Odpowiedź jest prosta, ponieważ sam Beacon Chain nie miał możliwości transferu tokenów ani przetwarzania transakcji, ponieważ nie mógł natywnie obsługiwać depozytów tokenów. Eth1 data zawiera trzy pod-pola: , który jest rootem Merkle drzewa kontraktu depozytowego, całkowita liczba depozytów dokonanych w kontrakcie, oraz hash referencyjnego bloku eth1. deposit root deposit count, block hash, Beacon Chain nie może po prostu ufać widokowi jednego walidatora na łańcuch Eth1, ponieważ różni walidatorzy mogą widzieć różne stany z powodu opóźnień sieciowych, dlatego używa mechanizmu głosowania, który pozwala proposerom bloków uwzględniać swój widok bieżących danych Eth1 w swoim bloku. Głosy te gromadzą się na tej liście przez okres głosowania, a jeśli jakakolwiek wartość uzyska ponad połowę głosów w tym okresie, staje się nowymi danymi Eth1. Na koniec okresu głosowania lista jest czyszczona i głosowanie rozpoczyna się od nowa. Eth Deposit Index śledzi, ile depozytów z kontraktu depozytowego zostało przetworzonych do tej pory. Kiedy łańcuch przetwarza nowy blok, sprawdza, czy są nieprzetworzone depozyty, porównując ten indeks z polem deposit count w Eth1 data. Jeśli deposit count jest wyższy, blok musi zawierać kolejne depozyty do maksymalnej liczby depozytów na blok, która wynosiła wtedy 16. Rejestr validators: List[Validator, VALIDATOR_REGISTRY_LIMIT] balances: List[Gwei, VALIDATOR_REGISTRY_LIMIT] Ta zmienna zasadniczo przechowuje listę osób uczestniczących w konsensusie i ile stawków posiadają. Ciekawostką dotyczącą pola walidatorów jest to, że ono tylko rośnie i nigdy nie maleje, nawet po wycofaniu się walidatora, jego wpis pozostaje na liście. Obecnie jest 2 210 484 wpisów, a tylko 962 941 jest aktywnych. Pole Validator ma osiem pod-pól: , czyli klucz publiczny walidatora, , gdzie trafia ich stawka po wycofaniu, ich saldo zaokrąglone w dół do najbliższego gwei, używane do obliczania nagród i kar, i jest aktualizowane tylko na granicach epoki z histerezą, aby zapobiec jego migotaniu w górę i w dół. , flaga boolean używana do oznaczenia, czy walidator został przycięty. , numer epoki, w której walidator stał się uprawniony do aktywacji. epoka, w której został aktywowany. , epoka, w której opuścił sieć, i wreszcie , epoka, w której saldo może zostać wycofane. pubKey withdrawable credentials effective balance, slashed activation eligibility epoch activation epoch, exit epoch withdrawable epoch Aby wskazać, dlaczego mamy pole effective balance w liście walidatorów i pole balances bezpośrednio w stanie Beacon, jest to, że pole effective balance nie jest aktualizowane w momencie, gdy Twoje rzeczywiste salda są, jest bufor, aby zapobiec cofaniu się i cofaniu. Bez histerezy, walidator krążący wokół 32 ETH, powiedzmy fluktuujący między 31,99 a 32,01 w każdej epoce z powodu nagród i kar, miałby swoje effective balance przeskakujące między 31 a 32 w każdej epoce. Oznaczałoby to ciągłe ponowne tworzenie Merkle obiektu walidatora i zmienianie jego wagi w obliczeniach komitetu w każdej epoce. Losowość randao_mixes: Vector[Bytes32, EPOCHS_PER_HISTORICAL_VECTOR] randao_mixes to lista o stałym rozmiarze 65 536 (około 2^16) wpisów. Za każdym razem, gdy walidator proponuje blok, dodaje do listy tak zwane „randao reveal”. To ujawnienie to zasadniczo bieżący numer epoki podpisany przez walidatora. Po podpisaniu łańcuch pobiera go i wykonuje na nim operację XOR z ostatnią mieszanką dla bieżącej epoki, co daje nową mieszankę. Wszyscy proposerzy w epoce robią to samo, aby uzyskać ostateczną skumulowaną mieszankę dla następnej epoki. Mieszanka randao służy do określenia komitetu i proposerów bloków dla następnej epoki. Komitet, czyli wszyscy aktywni walidatorzy podzieleni na 32 sloty, jest określany przez algorytm tasowania „swap-or-not”. Algorytm ten zasadniczo po prostu losowo zamienia indeks walidatora z mieszanką. Do wyboru proposerów bloków łańcuch hashuje mieszankę randao, tworząc ziarno. Następnie iteruje przez wszystkich aktywnych walidatorów, zaczynając od losowego przesunięcia pochodzącego z tego ziarna. Dla każdego kandydata sprawdza, czy hash ziarna i indeks walidatora, podzielony przez effective balance walidatora, przekracza próg. Jeśli tak, walidator staje się proposerem, jeśli nie, przechodzi do następnego. W praktyce znajduje go szybko, ponieważ większość aktywnych walidatorów ma saldo 32 ETH. Slashings slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR] Walidator jest przycinany z dwóch powodów: proponuje dwa różne bloki dla tego samego slotu, próbując stworzyć fork, lub składa sprzeczne atestacje. Pole slashings to lista o stałym rozmiarze 8192 wpisów, po jednym na epokę. Zawiera sumę wszystkich effective balance walidatorów, które zostały przycięte. To pole służy do obliczania wysokości kary. Atestacje previous_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH] current_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH] Każdy aktywny walidator składa atestację raz na epokę, a te atestacje napędzają zarówno regułę wyboru forka (LMD-GHOST), jak i mechanizm finalizacji (Casper FFG). Atestacja zawiera sześć pod-pól: , dla którego walidator dokonuje atestacji, to blok, który walidator uważa za szczyt łańcucha, jest on uważany za głos LMD-GHOST walidatora używany do określenia wyboru forka. to punkt kontrolny epoki, który walidator uważa za uzasadniony, a to bieżąca epoka, dla której walidator dokonuje atestacji, oba razem tworzą głos Casper FFG używany do finalizacji. Mówiąc prościej, walidator potwierdza, że epoka źródłowa powinna zostać sfinalizowana, a epoka docelowa powinna zostać uzasadniona. wskazuje, który walidator w komitecie dokonał atestacji. Ponieważ taniej jest łączyć rzeczy jako bity w bajcie, bit agregacji jest przechowywany w polu bitowym dla efektywności pamięci. Na koniec mamy walidatora nad danymi atestacji. slot beacon block root source target aggregation bits signature Finalizacja justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH] previous_justified_checkpoint: Checkpoint current_justified_checkpoint: Checkpoint finalized_checkpoint: Checkpoint Finalizacja oznacza, że blok i wszystkie jego transakcje nigdy nie mogą zostać cofnięte. W Beacon Chain finalizacja jest absolutna. Gdy epoka zostanie sfinalizowana, jedynym sposobem na jej cofnięcie jest przycięcie 1/3 wszystkich postawionych ETH, co kosztowałoby miliardy dolarów. Justification bits to wektor bitowy o długości 4, zasadniczo śledzi, czy ostatnie cztery epoki zostały uzasadnione. Poprzedni uzasadniony punkt kontrolny to punkt kontrolny, który był uzasadniony w poprzedniej epoce. Bieżący uzasadniony punkt kontrolny to najnowszy uzasadniony punkt kontrolny, podczas gdy Sfinalizowany punkt kontrolny to najnowszy sfinalizowany punkt kontrolny. Epoka staje się uzasadniona, gdy 2/3 całkowitej aktywnej stawki potwierdzi większość linków wskazujących na tę epokę jako cel. Finalizacja następuje, gdy uzyskasz dwa uzasadnione punkty kontrolne z rzędu. W momencie, gdy drugi zostanie uzasadniony, pierwszy zostaje podniesiony do poziomu zfinalizowanego, chociaż jest tam jeszcze kilka niuansów. Maszyna stanowa Teraz, gdy wiemy, co zawiera stan, możemy przyjrzeć się, jak się zmienia. Co 12 sekund nadchodzi nowy slot. Jeśli blok zostanie zaproponowany, funkcja przejścia stanu przyjmuje obecny stan i ten blok, przeprowadza walidację, aktualizuje i zwraca nowy stan. Proces ten jest podzielony na trzy etapy zgodnie ze specyfikacją: przetwarzanie slotu, przetwarzanie bloku i przetwarzanie epoki. Przetwarzanie Slotu Przetwarzanie slotu odbywa się za każdym razem, gdy łańcuch musi przejść z jednego slotu do następnego, niezależnie od tego, czy blok został wyprodukowany. Gdy slot przechodzi z N do N+1, dzieją się trzy rzeczy. Po pierwsze, root stanu dla slotu N jest aktualizowany, aby zachować zapis, jak wyglądał slot w tym slocie. Po drugie, nagłówek najnowszego bloku, który przechowuje nagłówek ostatnio przetworzonego bloku, jest również aktualizowany, pamiętaj, że to pole służy do zapobiegania duplikatom bloków. Również root tego ukończonego nagłówka jest zapisywany w block root. Na koniec licznik slotów jest zwiększany o jeden. Możesz się zastanawiać, co dzieje się ze stanem, gdy proposer przegapi swój slot. Cóż, wszystkie stany nadal są aktualizowane, na przykład block roots tego slotu będą zawierać root tego samego najnowszego nagłówka bloku, ponieważ nie przybył żaden nowy blok, aby go zastąpić. Po zwiększeniu slotu, łańcuch sprawdza, czy właśnie przekroczył granicę epoki, co można łatwo zrobić za pomocą `slot mod 32 == 0`. Jeśli tak, przetwarzanie epoki rozpoczyna się, zanim cokolwiek innego się stanie. Więc technicznie, dla każdego 32 slotów, przetwarzanie epoki odbywa się obok przetwarzania slotu, innymi słowy, przetwarzanie epoki odbywa się po przejściu slotu, ale przed przetworzeniem bloku dla tego slotu. Ostatni fakt, o którym warto wspomnieć, to to, że gdy docieramy do punktu, w którym tablice state roots i block roots są wypełnione, czyli w pozycji `slot mod 8192 == 0`, zanim obie tablice zaczną być nadpisywane nowymi danymi, ponieważ wydaje się to cykliczne, łańcuch hashuje oba pola razem i dodaje je do historycznego stanu. Przetwarzanie Bloku Przetwarzanie bloku odbywa się, gdy blok jest faktycznie proponowany dla slotu. Po tym, jak przetwarzanie slotu przesunie stan do odpowiedniego slotu, przetwarzanie bloku bierze podpisany blok i stosuje jego zawartość do stanu. Ma dwa główne części: walidację nagłówka bloku i przetwarzanie ciała bloku. Przede wszystkim łańcuch sprawdza kilka rzeczy, takich jak czy nagłówek bloku pasuje do bieżącego slotu stanu, i czy indeks proposera bloku jest faktycznie walidatorem, który został wybrany przez randao. Na koniec sprawdza, czy root rodzica bloku odpowiada rootowi najnowszego nagłówka bloku. Jeśli zostanie zwalidowany, nagłówek bloku jest przechowywany jako najnowszy nagłówek bloku w stanie. Następnie proposer musi dołączyć randao reveal, które, jak już wspomniałem, jest zasadniczo bieżącym numerem epoki podpisanym przez walidatora. Łańcuch weryfikuje podpis na podstawie klucza publicznego proposera. Łatwo zauważyć, że ta obecna metoda jest deterministyczna, że podpis walidatora zawsze będzie taki sam dla tego samego numeru epoki, prawda, w rzeczywistości cały punkt robienia tego w ten sposób polega na tym, aby pozwolić każdemu użyć klucza publicznego walidatora do sprawdzenia numeru epoki, który walidator faktycznie podpisał. Należy zauważyć, że proposer nie może pominąć randao reveal; jeśli proponuje blok, musi go uwzględnić, jedynym sposobem na pominięcie procesu jest nieproponowanie bloku w pierwszej kolejności. Po tym proposer dołączy również swój widok stanu kontraktu depozytowego łańcucha Eth1 jako głos Eth1 data. Jeśli jakakolwiek wartość Eth1 data na liście głosów osiągnie większość, staje się ona nowymi danymi Eth1 w stanie. Podczas przetwarzania bloku, pole proposer slashing zawiera dowody na to, że walidator podpisał dwa różne nagłówki bloków dla tego samego slotu. Łańcuch weryfikuje oba podpisy, a jeśli są prawidłowe, przycina walidatora, najpierw ustawiając jego flagę slashed na true, i dodając jego effective balance do tablicy slashings. Podobnie dla attesterów, jeśli istnieją sprzeczne atestacje, łańcuch je weryfikuje i identyfikuje winnych walidatorów za pomocą ich podpisu, a następnie przycina tych walidatorów, w taki sam sposób i proces jak przycinanie proposerów bloków. Nowe atestacje w bloku są walidowane, atestacja jest konwertowana na oczekującą atestację poprzez dodanie dwóch nowych pól: inclusion delay i proposer index, a następnie są one dodawane do atestacji bieżącej epoki lub poprzedniej epoki. Nic szczególnego po dodaniu, ponieważ nie wpływają one natychmiast na stan, leżą tam do czasu przetworzenia epoki. Nowe depozyty walidatorów z kontraktu depozytowego Eth1 są przetwarzane, blok musi zawierać wszystkie oczekujące depozyty do maksymalnej liczby 16. Łańcuch weryfikuje dowód Merkle każdego depozytu na podstawie deposit root, aby zapewnić jego poprawność. Jeśli klucze publiczne deponentów są nowe, dodawany jest nowy wpis walidatora, a także odpowiednie saldo. Walidator może zasygnalizować, że chce odejść, składając podpisane dobrowolne wyjście. Łańcuch sprawdza, czy walidator był aktywny przez co najmniej 256 epok, i czy bieżąca epoka jest co najmniej epoką wyjścia, która jest określona. Jeśli wszystko się zgadza, ustawiane są epoka wyjścia i epoka wycofania walidatora. Po przetworzeniu wszystkiego powyższego, pozostaje jeszcze jeden ważny element: obliczony root stanu przez inny węzeł jest porównywany z rootem stanu zawartym w bloku. Jeśli się nie zgadzają, cały blok jest odrzucany. Przetwarzanie Epoki Przetwarzanie epoki jest uruchamiane na granicy epoki, czyli co krok `slot mod 32 = 0`. Działa ono podczas przetwarzania slotu, gdy licznik slotów przechodzi do nowej epoki. Jest to najbardziej złożony etap, ponieważ większość fajnych rzeczy związanych z konsensusem dzieje się tutaj. Najpierw następuje uzasadnienie i finalizacja, tutaj działa Casper FFG. Proces może wydawać się skomplikowany, ale jest bardzo prosty. Mówiąc prosto, łańcuch patrzy na atestacje z poprzedniej epoki i liczy effective balance walidatorów, którzy złożyli atestacje z poprawnym celem. Jeśli ta suma wynosi co najmniej 2/3 całkowitego aktywnego salda, epoka docelowa staje się uzasadniona, a jeśli dwie kolejne epoki są uzasadnione, wcześniejsza staje się zfinalizowana. Łatwe! Jedna rzecz, której nie wspomniałem w etapie przetwarzania bloku, polega na tym, że dla każdego etapu walidatorzy gromadzą nagrody, otrzymują nagrody za uwzględnianie atestacji, za dodawanie dowodów przycinania, a nawet normalną podstawową nagrodę. Te skumulowane nagrody są oceniane przez łańcuch w ciągu poprzedniej epoki na etapie przetwarzania epoki i odpowiednio dostosowywane są ich salda. Jeśli łańcuch nie został sfinalizowany od ponad czterech epok, wchodzi w życie coś, co opisano jako „wyciek nieaktywności”. Oprócz normalnych kar za brak atestacji, nieuczestniczący walidatorzy ponoszą dodatkową karę za nieaktywność, która rośnie kwadratowo z każdą epoką od ostatniej sfinalizowanej epoki. Innymi słowy, im dłużej blok nie jest finalizowany, tym surowsza jest kara. Możesz się zastanawiać, jaki jest cel tego. Otóż, gdy blok nie jest finalizowany od dłuższego czasu, oznacza to, że nie ma większościowego głosu w tym bloku, a ponieważ głosowanie na finalizację jest mierzone przez wagę effective balance walidatora, czyli zasadniczo ile ETH ma walidator, zmniejszenie jego effective balance zmniejsza jego siłę głosu. Tym samym Ethereum wykorzystuje to jako sposób na wymuszenie finalizacji bloków. Warto zauważyć, że podczas wycieku nieaktywności nawet prawidłowi attesterzy nie otrzymują nagród. Wszystko przenosi się w tryb czystej kary, aby przyspieszyć rebalansowanie. Innym ważnym wydarzeniem, które ma miejsce na tym etapie, jest aktywacja walidatorów, których epoka kwalifikowalności do aktywacji została osiągnięta. Również walidatorzy, których epoka wyjścia nadeszła, są usuwani z aktywnego zestawu walidatorów. Następnie pamiętaj, że effective balance nie jest aktualizowane z każdym slotem i epoką, ponieważ obowiązuje histereza. Aktualizuje się tylko wtedy, gdy rzeczywiste saldo wystarczająco wzrośnie powyżej bieżącego progu górnego effective balance, effective balance zwiększa się o 1 ETH, a jeśli spadnie poniżej progu dolnego, zmniejsza się o 1 ETH. Na koniec mieszanka randao bieżącej epoki jest kopiowana do slotu następnej epoki. Jak widać wyraźnie, przetwarzanie epoki jest najbardziej skomplikowaną częścią maszyny stanowej i jest nieprzyjazne obliczeniowo, dlatego zawsze prowadzi do wielu prac optymalizacyjnych dla inżynierów tworzących klientów łańcucha. Od Fazy 0 do Fulu BeaconState, przez który przeszliśmy do tej pory, to wersja z Fazy 0, oryginalna. Ale Beacon Chain jest żywym systemem. Każdy fork warstwy konsensusu zmodyfikował BeaconState, albo dodając nowe pola, usuwając stare, albo po prostu zmieniając sposób działania niektórych istniejących. Na przykład, w fork Altair, listy atestacji z poprzedniej i bieżącej epoki zostały całkowicie usunięte, aby zastąpić je z poprzedniej i bieżącej epoki, przy czym różnica polegała na tym, że podczas gdy poprzednia przechowywała pełne obiekty atestacji, nowy typ participation przechowywał je tylko w formie bitowej. Teraz każdy walidator otrzymuje tylko trzy bity na epokę, reprezentujące, czy poprawnie określił źródło, cel i szczyt. Doprowadziło to do drastycznego zmniejszenia rozmiaru pamięci. Bellatrix, fork związany z The Merge, wprowadził pole execution payload do beaconState; pole to służy do połączenia warstwy konsensusu i warstwy wykonania. Pola Eth1 zostały zachowane, ale ich role zostały zmniejszone, ponieważ nie były już potrzebne. participation Fork Capella wprowadził możliwość wycofania środków przez walidatora, rejestruje to, dodając nowe pole o nazwie next withdrawal index do beaconState. Historical roots zostały zastąpione przez historical summaries, które przechowują block root i state root w strukturze zamiast hashować je razem. Fork Deneb z drugiej strony miał prawie zerowy wpływ na beaconState, ponieważ fork dotyczył głównie blobów. W Electra i Fulu kluczową zmianą było podniesienie maksymalnego effective balance z 32 ETH do 2048 ETH, co doprowadziło do wprowadzenia nowych pól w beaconState. Każdy fork budował na poprzednim, a BeaconState urósł z 21 pól w Fazie 0 do ponad 30 w Fulu. Jedna rzecz jest stała: od Fazy 0 do Fulu stan się powiększał, forki dodawały pola, forki usuwały pola, ale architektura pozostała taka sama. Wniosek Beacon Chain jest często opisywany jako skomplikowany, tak, zgadzam się, ponieważ jest skomplikowany. Ale u jego podstaw jest to zasadniczo cykl: stan istnieje, przybywa wejście, istniejący stan jest aktualizowany, aby wyprodukować nowy stan, a następnie powtórz! Proste! To, co czyni Beacon Chain naprawdę niezwykłym, to nie pojedyncze pole, ale sposób, w jaki wszystko jest połączone, aby dać nam to wspaniałe „tek”, które mamy dzisiaj! Bibliografia Specyfikacje Konsensusu Ethereum (Faza 0) Specyfikacja Ethereum Anotowana autorstwa Bena Edgingtona eth2book.info Gasper: Łączenie GHOST i Caspera (Oryginalny artykuł) Casper the Friendly Finality Gadget (Oryginalny artykuł)